go语言的爬取网站信息上
基本流程
首先根据url,获取网站的html信息,然后提取出所需的内容
因为网页的编码方式不同,有的中文会编程乱码,所以需要转码
另外提取内容,需要使用正则表达式来匹配
转码
引用包
go get golang.org/x/text
使用transform.NewReader新建一个utf8编码的Reader,需要参数io.Reader和网页原本的编码格式
如果网页是GBK编码,可以直接转
//这里resp为使用http.Get("url地址")获取到的,resp.body为一个Reader
utf8Reader := transform.NewReader(resp.body,simplifiedchinese.GBK.NewDecoder())
但如果不知道原网页是什么编码格式,就需要识别一下
引用包
go get golang.org/x/net/html
使用charset.DetermineEncoding方法获取编码格式
//取出原本Reader的前1024个字节新建一个Reader,然后识别
r,_ := bufio.NewReader(resp.body).Peek(1024)
//当网页编码格式为GBK时,这里的e就相当于之前的simplifiedchinese.GBK
e := charset.DetermineEncoding(r,"")
正则表达式
使用regexp.Compile来匹配
格式
.代表任意字符
*代表0到多个
代表1到多个
[a-z]代表所有小写字母
[A-Z]代表所有大写字母
[0-9]代表所有数字
[^>]代表不为>的字符
[\s]代表任意空白字符
const origen string = "原始内容"
const content string = `匹配内容`
//如果能够确保匹配到,可以使用MustCompile方法
r,_ := regexp.Compile(content)
//FindAll传入的是[]byte,返回的是[][]byte,如果想要string,可以使用FindAllString
m := r.FindAll(origen,-1)
具体实现
首先需要根据url获取网页内容,可以将这一部分封装到一个包中
package fetcher
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"golang.org/x/net/html/charset"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
)
//获取网页内容的函数
func Fetch(url string) ([]byte,error){
resp,err := http.Get(url)
if err != nil{
return nil,err
}
defer resp.body.Close()
if resp.StatusCode != http.StatusOK{
return nil,fmt.Errorf("fetch error no statusok")
}
//获取网页编码格式
e := determineEncoding(resp.body)
utf8Reader := transform.NewReader(resp.body,e.NewDecoder())
b,err := ioutil.ReadAll(utf8Reader)
if err != nil{
return nil,err
}
return b,nil
}
func determineEncoding(i io.Reader) encoding.Encoding{
//先取出前1024个自己新建一个Reader
re,err := bufio.NewReader(i).Peek(1024)
if err != nil{
log.Printf("error : %v",err)
return unicode.UTF8
}
//获取Reader的编码格式
e,_,_ := charset.DetermineEncoding(re,"")
return e
}
然后需要定义一些类型,来存储入参和出参
提取网页内容的函数返回结果是一个url和一个内容,这个url还会继续被用来爬取,但是提取方法不一样,因此可以将返回结果的属性设为一个requests和一个items,request中又包括url和具体的提取方法parseFunc
package engine
type Request struct{
URL string
ParseFunc func(content []byte) ParseResult
}
type ParseResult struct{
Requests []Request
//[]interface{}代表任意类型
Items []interface{}
}
//这里是一个空的提取方法,因为这篇文章只会先写第一层的提取方法,所以在进行下一层提取时,先传一个空的提取方法
func NilParseFunc(content []byte) ParseResult{
return ParseResult{}
}
第一层提取方法的实现
package parser
const con string = `<a href="https://blog.csdn.net/m0_46606984/article/details/([^"]*)"[\s][^>]*>([^<]*)`
func ParseCityList(content []byte) engine.ParseResult{
r,_ := regexp.Compile(con)
m := r.FindAll(content,-1)
var result engine.ParseResult
for _,mm := range m{
//这里使用string(mm[2]),是为了后面打印出来直接可以用%s
result.Items = append(result.Items,string(mm[2]))
result.Requests = append(result.Requests,engine.Request{mm[1],engine.NilParseFunc})
}
return result
}
具体的运行方法
package engine
func Run(seeds ...Request){
var requests []Request
for s := range seeds{
requests = append(requests,s)
}
for len(requests) > 0{
r := requests[0]
requests = requests[1:]
b,_ := fetcher.Fetch(r.URL)
result := r.ParseFunc(b)
for _,m := range result.Items{
fmt.Printf("%s\n",m)
}
}
}
在main函数中直接调用运行方法Run
package main
const url string = "localhost:8080/zhenai"
func main(){
engine.Run(engine.Request{url,parser.ParserCityList})
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgefagb
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01