⼿把⼿教你如何获取全⽹可访问的所有⽹站⽹址和⽹站信息
# 如何获取全⽹可访问的所有⽹站⽹址和⽹站信息呢
今天由于有⼀个⼩程序项⽬,是专门给织梦dedecms⽹站、WordPress⽹站做⼩程序制作免费⼩程序的。但是⼿上织梦⽹站和WordPress⽹站⽤户数量都不是很多,很好的项⽬却没有触及到⽤户,没有能给⽹站带来好处,于是就想,能不能收集现在⽹上所有的织梦⽹站和WordPress⽹站,并且获取他们的邮箱、QQ、、电话等有⽤信息呢?
带着疑问百度了⼀番,没有发现现成的可⽤数据,可是⼩程序项⽬还得往前推呢,等着⽤户来使⽤呢?既然⽹上没有现成的,要不就⾃⼰写⼀个吧。于是就有了这个cobweb全⽹⽹址采集器。
## 全⽹⽹址采集器是什么?
这是⼀个由golang编写的全⽹⽹址采集器,可⽤⾃动爬取可触及的所有⽹站信息。该⽹址采集器会⾃动采集并分析⽹站的标题、站点描述、、QQ、、⽹站所⽤的运⾏环境、ip信息等,甚⾄是⽹站所⽤的框架。
## 为什么会有这个全⽹⽹址采集器
* 因为我想收集现在全⽹的⽹址,并分析⽹站数据。
## 全⽹⽹址采集器能采集哪些内容
本采集器可以采集到的的内容有:⽂章标题、⽂章关键词、⽂章描述、⽂章详情内容、⽂章作者、⽂章发布时间、⽂章浏览量。
##全⽹⽹址采集器可⽤在哪⾥运⾏
本采集器可⽤运⾏在 Windows系统、Mac 系统、Linux系统(Centos、Ubuntu等),可⽤下载编译好的程序直接执⾏,也可以下载源码⾃⼰编译。
## 如何安装使⽤
* 下载可执⾏⽂件
请从Releases 中根据你的操作系统下载最新版的可执⾏⽂件,解压后,重命名config.dist.json为config.json,打开config.json,修改mysql 部分的配置,填写为你的mysql地址、⽤户名、密码、数据库信息,新建cobweb数据库,导⼊mysql.sql到填写的数据库中,然后双击运⾏可执⾏⽂件即可开始采集之旅。
* ⾃助编译
先clone代码到本地,本地安装go运⾏环境,在cobweb⽬录下打开cmd/Terminal命令⾏窗⼝,执⾏命。如果你没配置代理的话,还需要新设置go的代理
```shell script
```
最后执⾏下⾯命令
```shell script
gomod tidy
gomod vendor
gobuild
```
编译结束后,配置config。重命名config.dist.json为config.json,打开config.json,修改mysql部分的配置,填写为你的mysql地址、⽤户名、密码、数据库信息,新建cobweb数据库,导⼊mysql.sql到填写
的数据库中,然后双击运⾏可执⾏⽂件即可开始采集之旅。
### config.json配置说明
```
{
"mysql": { //数据库配置
"Database": "spider",
"User": "root",
"Password": "root",
"Charset": "utf8mb4",
"Host": "127.0.0.1",
"TablePrefix": "",
"Port": 3306,
"MaxIdleConnections": 1000,
"MaxOpenConnections": 100000
}
}
```
## 全⽹⽹址采集器运⾏原理分析
### 多线程(多协程)同时执⾏
全⽹⽹址采集器利⽤了golang得天独厚的并⾏任务优势,同时开启多个协程,可以做到⽐常规轻易得⼿的php采集代码快10倍~100倍,甚⾄更快。当然更快的采集速度还需要依靠你本地的⽹速,你家开的是500M带宽的话,开1000个协程都是可以的。
相关代码部分
```go
var MaxChan = 100
var waitGroup sync.WaitGroup
var ch = make(chan string, MaxChan)
func SingleSpider(){
var websites []Website
var counter int
DB.Model(&Website{}).Where("`status` = 0").Limit(MaxChan*10).Count(&counter).Find(&websites) if counter > 0 {
for _, v := range websites {
ch <- v.Domain
waitGroup.Add(1)
go SingleData2(v)
}
} else {
log.Println("等待数据中,10秒后重试")
time.Sleep(10 * time.Second)
}
SingleSpider()
}
```
### 采集数据锁,最⼤限度保证数据不被多次执⾏
为了防⽌数据被多次执⾏,采集过程中还采⽤了数据锁,让下⼀次采集的时候,不会读到相同的数据。
相关代码
```go
//锁定当前数据
DB.Model(&website).Where("`id` = ?", website.ID).Update("status", 2)
log.Println(fmt.Sprintf("开始采集:%s://%s", website.Scheme, website.Domain))
err := website.GetWebsite()
if err == nil {
website.Status = 1
} else {
website.Status = 3
}
log.Println(fmt.Sprintf("⼊库2:%d:%s",website.ID, website.Domain))
DB.Save(&website)
```
### 快速⼊库,直接执⾏原⽣sql语句
本来代码中采⽤的是gorm的orm形式插⼊数据,结果发现使⽤orm的话,插⼊⼀条⽹址需要执⾏3条sql 语句,这在并⾏执⾏中,每多执⾏⼀条sql都是浪费,因此,采⽤了原⽣sql来插⼊数据,每次只需要执⾏⼀条数据即可。
相关源码
```go
DB.Exec("insert into website(`domain`, `scheme`,`title`) select ?,?,? from dual where not exists(select id from website where `domain` = ?)", v.Domain, v.Scheme, v.Title, v.Domain)
```
### ⽹站编码⾃动识别并转换为utf-8
由于是采集全⽹的⽹址,并且要从⽹站内容⾥⾯分析有⽤的数据,并且golang只⽀持utf-8,什么乱七⼋糟的编码格式⽹站内容,都需要转换为utf-8,因此编码转换这⼀步必不可少,全⽹⽹址采集器内置了功能强⼤的编码转换器,不⽤担⼼编码转换问题,同时兼容多种编码格式。
相关代码
```go
contentType := strings.ToLower(resp.Header.Get("Content-Type"))
log.Println(contentType)
var htmlEncode string
if contentType == "" {
//先尝试读取charset
reg := regexp.MustCompile(`(?is)charset=["']?\s*([a-z0-9\-]+)`)
match := reg.FindStringSubmatch(body)
if len(match) > 1 {
htmlEncode = strings.ToLower(match[1])
if htmlEncode != "utf-8" && htmlEncode != "utf8" {
body = ConvertToString(body, "gbk", "utf-8")
}
} else {
reg = regexp.MustCompile(`(?is)]*>(.*?)<\/title>`)
match = reg.FindStringSubmatch(body)
if len(match) > 1 {
aa := match[1]
_, htmlEncode, _ = charset.DetermineEncoding([]byte(aa), "")
if htmlEncode != "utf-8" {
body = ConvertToString(body, "gbk", "utf-8")
}
}
}
} else if !strings.Contains(contentType, "utf-8") {
body = ConvertToString(body, "gbk", "utf-8")
}
```
### ⽹站内容⾃动提取
⽹站信息抓取回来了,还是html状态,需要从中提取出有⽤的信息,才达到我们想要的最终⽬的,内置了qq采集、采集、电话采集等功能。相关代码
```go
免费源码下载网站有哪些//尝试获取
reg := regexp.MustCompile(`(?i)(|客服|号|咨询|服务)\s*(:|:|\s)\s*([a-z0-9\-_]{4,30})`)
match := reg.FindStringSubmatch(contentText)
if len(match) > 1 {
website.WeChat = match[3]
}
//尝试获取QQ
reg = regexp.MustCompile(`(?i)(QQ|QQ客服|QQ号|QQ号码|QQ咨询|QQ联系|QQ交谈)\s*(:|:|\s)\s*([
0-9]{5,12})`)
match = reg.FindStringSubmatch(contentText)
if len(match) > 1 {
website.QQ = match[3]
}
//尝试获取电话
reg = regexp.MustCompile(`([0148][1-9][0-9][0-9\-]{4,15})`)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论