半小时学会网络爬虫-Go和python两种语言实现,带你白嫖小说

2022-07-07 15:40:19 浏览数 (1)

01

前言

大家好,我是asong,这是我的第四篇原创文章,这一文,我将介绍网络爬虫系列的教程,使用GO和python分别实现最简单的爬虫------爬取小说。其实这篇文章就是教大家怎么白嫖,在这个网站广告铺天盖地的环境下,我们想单纯的的看会小说也成了一个问题,所以我们就可使用爬虫技术,把小说爬下来,就不用看烦人的广告了。话不多说,开整...

02

什么是爬虫

对于这种问题,我们可以直接去百度百科看介绍,网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。看看,百度百科介绍的多么好,多么通俗易懂。

网络爬虫有什么用呢?网络爬虫是大数据行业获取数据的核心工具。没有网络爬虫自动地、不分昼夜地、高智能地在互联网上爬去免费的数据,那些大数据相关的公司恐怕要少四分之三。现在的爬虫基本上都是围绕web网页的,所以我们爬虫就是根据网页地址(URL)爬取网页内容,网页地址就是我们在浏览器中输入的网站链接。例如我们常用的百度:https://www.baidu.com,这就是一个URL。URL专业的叫法是统一资源定位符,格式如下:

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

URL 的格式主要由前个三部分组成:

  • protocol:第一部分就是协议,例如百度使用的就是https协议;
  • hostname[:port]:第二部分就是主机名(还有端口号为可选参数),一般网站默认的端口号为80,例如百度的主机名就是www.baidu.com,这个就是服务器的地址;
  • path:第三部分就是主机资源的具体地址,如目录和文件名等。

所以有了URL,我们就可以去指定位置获取我们想要的数据信息。有了数据,我们需要对数据进行分析,所以就引出了爬虫另一项必备技能:审查元素。

我们在浏览器浏览的每一个网页,我们都可以查看其网页源码,也就是HTML。这些HTML就决定了网站的原始容貌。这里就不介绍HTML的具体使用了,想要学习的网络资源很多。比如我们使用Chrome 浏览器,在谷歌首页我们右键点击检查(其他浏览器不同,这里不做介绍),在右侧就会出现一大堆代码,这些代码,就叫做HTML。

浏览器就是作为客户端从服务器端获取信息,然后将信息解析,并展示给我们。所以我们根据HTML就可以分析出网页内容。好啦,基本的基础知识已经知道了,下面就开始我们的实践吧!!!

03

爬虫实例

  1. 爬取网站小说介绍

这里的实例,我们下载文字内容,也就是下载一本小说。小说网站,我们选择的新笔趣阁。链接:https://www.xsbiquge.com/。

这个网站只支持在线浏览,不支持小说打包下载,所以我们就可以使用我们的爬虫技术下载一本小说,解决不能本地看小说的问题。由于本人不看小说,所以直接去小说排行榜选了第一名,《三国之他们非要打种地的我》。名字就很有吸引力嘛!!!!

2. 相关技术介绍

本次教程使用两种语言进行开发,分别是Golang和Python。Golang我们使用自带的HTTP库进行网站获取和google自己维护的库x/net/html进行网页数据解析。Python我们使用requests库进行网页获取,使用BeautifulSoup进行网页数据解析。

2.1 golang.org/x/net/html

x/net/html是google自己维护的库,主要可以帮助我们解析网页数据,我们只需要导入golang.org/x/net/html这个包就可以,使用方法也挺简单,就不在这里做具体介绍,可以到GO圣经:https://godoc.org/golang.org/x/net/html#Parse

进行学习,里面有样例,很好懂。

2.2 BeatifulSoup

BeautifulSoup是python的一个第三方库,主要帮助我们解析网页数据。我们要使用这个工具,需要提前进行安装,在cmd中,我们使用pip命令进行安装,命令如下:

pip install beautifulsoup4

安装好之后,我们还需要安装lxml,这是解析HTML需要用到的依赖:

pip install lxml

这就可以使用了,具体的学习教程可以到官方中文教程:

https://beautifulsoup.readthedocs.io/zh_CN/latest/

2.3 requests

requests库很强大,我们可以使用requests库进行网页爬取。requests库是第三方库,需要我们自己安装。安装简单,使用pip命令即可安装:

pip install requests

requests库的github地址:

https://github.com/requests/requests

具体学习可以按demo进行学习。

3. 爬虫步骤

总共就分为三步:

  • 第一步:发起请求,我们需要明确如何发起HTTP请求,获取到数据。
  • 第二步:解析数据,获取到的数据乱七八糟的,我们需要提取出我们想要的数据。
  • 第三步:保存数据:将我们想要的数据,保存下载。

4. 开始实践

备注:

我已将我整个项目上发到我的github上面了。Golang代码GitHub地址如下:

https://github.com/sunsong2020/Golang_Dream/tree/master/reptile_go

Python代码Github地址如下:

https://github.com/sunsong2020/Golang_Dream/tree/master/reptile_py

4.1 获取网页

我们完全按照步骤来,第一步,我们先获取网页数据。因为我们要获取整章的小说,所以我们先去查看小说目录,并查看它的网页源码,如下:

解析网页在下一节进行讲解。我们先获取目录网页,然后在获取文章网页,这样章节title和内容就对应起来了。小说第一章查看如下:

知道了这两个网页的地址,我们就可以获取网页了。

Golang可以使用标准库net/http进行网页获取,样例如下:

代码语言:javascript复制
resp,err := http.Get(target)
if err!=nil{
   fmt.Println("get err http",err)
   return err
}

直接调用Get方法即可,target就是要获取的网页URL。

Python可以使用requests库进行获取网页,样例如下:

代码语言:javascript复制
req = requests.get(url=target)
req.encoding = 'utf-8'
代码语言:javascript复制
html = req.text

直接调用get方法即可,target即URL,req.tex就说获取的网站内容,可以print打印一下看的更清楚。这里设置了编码方式为utf-8,本次爬取的网站本身就是utf-8编码,所以不需要转换,如果爬取的网站是GBK编码的就需要进行编码转换。

4.2 解析网页

获取到了网页,下面我们就开始进行解析网页。Golang我们使用x/net/html这个库,使用go get指令就可以获取到第三方库。代码样例如下:

代码语言:javascript复制
doc,err := html.Parse(resp.Body)
if err != nil{
   fmt.Println("html parse err",err)
   return err
}
parseList(doc)

直接调用Parse方法,将网页数据放入进去,返回一个解析树(文档元素)的根作为*Node,之后我们就可以以深度优先顺序处理每个节点标签。

我们先对文章目录进行分析,提取出文章标题和对应文章内容的URL参数。具体分析,我们需要查看部分网页源码如下:

我们可以看到,文章title都在a标签下,href属性存放的是URL参数。,而且他们都属于div标签,id等于list,这样我们就可以定位位置了。所以根据这个特点我们可以进行分析提取,Golang语言代码如下:

代码语言:javascript复制
//找到文章列表
func parseList(n *html.Node)  {
   if n.Type == html.ElementNode && n.Data == "div"{
      for _,a := range n.Attr{
         if a.Key == "id" && a.Val == "list"{
            listFind = true
            parseTitle(n)
            break
         }
      }
   }
   if !listFind{
      for c := n.FirstChild;c!=nil;c=c.NextSibling{
         parseList(c)
      }
   }
}
//获取文章头部
func parseTitle(n *html.Node)  {
   if n.Type == html.ElementNode && n.Data == "a"{
      for _, a := range n.Attr {
         if a.Key == "href"{
            //获取文章title
            for c:=n.FirstChild;c!=nil;c=c.NextSibling{
               buf.WriteString(c.Data  "n")
            }
            url := a.Val
            target := server   url // 得到 文章url
            everyChapter(target)
            num--
         }
      }
   }
   if num <= 0{
      return
   }else {
      for c := n.FirstChild;c!=nil;c=c.NextSibling{
         parseTitle(c)
      }
   }
}

这里我们提取到了文章的title,我们要实现的是title和内容对应起来,所以没获取一个title就可以去获取每一篇文章内容,这里依然需要去分析网页源码,这里网页URL,我们可以根据根URL 获取到的URL参数进行合并出的新URL就是内容所在位置,分析网页源码如下:

我们可以看到文章的内容都在div标签下,id等于content,所以只需要拿取其中数据就是文章内容。

因此使用Golang可以写出代码如下:

代码语言:javascript复制
//获取每个章节
func everyChapter(target string)  {
   fmt.Println(target)
   resp,err := http.Get(target)
   if err!=nil{
      fmt.Println("get err http",err)
   }
   defer resp.Body.Close()
   doc,err := html.Parse(resp.Body)
   find = false
   parse(doc)
代码语言:javascript复制
//解析文章
func parse(n *html.Node)  {
   if n.Type == html.ElementNode && n.Data == "div"{
      for _,a := range n.Attr{
         if a.Key == "id" && a.Val == "content" {
            find = true
            parseTxt(&buf,n)
            break
         }
      }
   }
   if !find{
      for c := n.FirstChild;c!=nil;c=c.NextSibling{
         parse(c)
      }
   }
}
//提取文字
func parseTxt(buf *bytes.Buffer,n *html.Node)  {
   for c:=n.FirstChild;c!=nil;c=c.NextSibling{
      if c.Data != "br"{
         buf.WriteString(c.Data "n")
      }
   }
}

好啦这就提取文章成功了,一步步分析标签即可。下面介绍Pyhton写法,因为Python有BeautifulSoup4这个库,代码量就很少了,看起来也很通俗易懂,Python代码样例如下:

代码语言:javascript复制
import requests # requests 包 进入url访问
from bs4 import BeautifulSoup
from tqdm import tqdm #tqdm是一个快速、可扩展的python进度条,可以在python长循环中添加一个进度提示信息

def get_content(target):
    req = requests.get(url=target)
    req.encoding = 'utf-8'
    html = req.text
    bs = BeautifulSoup(html,'lxml')
    texts = bs.find('div',id='content')
    content = texts.text.strip().split('xa0'*4)
    return content
if __name__ == '__main__':
    server = "https://www.xsbiquge.com"
    target = "https://www.xsbiquge.com/91_91600/"
    book_name = '三国之他们非要打种地的我.txt'
    req = requests.get(url=target)
    req.encoding = 'utf-8'
    html = req.text
    characters_name = BeautifulSoup(html,'lxml')
    characters = characters_name.find('div',id='list') # 寻找标签
    # 提出a标签
    characters = characters.find_all('a')
    #进行循环读取章节
    for character in tqdm(characters):
        # 得到href属性
        url = server   character.get('href')
        # 获取章节名字
        character_name = character.string
        # 获取文章
        content = get_content(url)

get_content函数用于获取每一章节的内容;直接调用find_all方法就可以找出所以标签a的内容,提取出所有的题目,代码量少,又很简单,不过缺少了底层分析,对于新手来说,用Golang写一篇会更加加深对网页分析的理解。

4.3 保存数据

数据已经解析好了,只差最后一步了,我们马上就可以看到心爱的小说啦,白激动,马上就好。这里我们使用一个记事本保存文章就可以。不过要注意格式的问题,要不导出的文字,看起来很别扭的。写入文件时,写完文章要换行换行,遇到br标签,就要进行换行,这样的文章才能有一个耐看的排版,Golang代码样例如下:

代码语言:javascript复制
    text,err := os.Create("三国之他们非要打种地的我.txt")
   if err!=nil{
      fmt.Println("get create file err",err)
   }
   file := strings.NewReader(buf.String())
   file.WriteTo(text)
}
代码语言:javascript复制
//提取文字
func parseTxt(buf *bytes.Buffer,n *html.Node)  {
   for c:=n.FirstChild;c!=nil;c=c.NextSibling{
      if c.Data != "br"{
         buf.WriteString(c.Data "n")
      }
   }
}

使用bytes.Buffer进行数据保存,遇到br标签就换行,很完美。

使用Python进行数据保存也是这样,代码如下:

代码语言:javascript复制
with open(book_name,'a',encoding='utf-8') as f:
    f.write(character_name)
    f.write('n')
    f.write('n'.join(content))
    f.write('n')

好啦这回所有的代码都写好了,就等待运行啦,运行结果片段如下:

看,没有了广告,文章还存储到了本地,终于可以安心看小说啦!!!

04

结尾

好啦,一个简单的爬虫做好了!!!你们学会了没。如果没有学会,直接查看我的源码,相信你一定可以看懂的。我已将我整个项目上发到我的github上面了。Golang代码GitHub地址如下:

https://github.com/sunsong2020/Golang_Dream/tree/master/reptile_go

Python代码Github地址如下:

https://github.com/sunsong2020/Golang_Dream/tree/master/reptile_py

0 人点赞