![Python数据预处理技术与实践](https://wfqqreader-1252317822.image.myqcloud.com/cover/321/27563321/b_27563321.jpg)
3.3 网络爬虫技术
网络数据采集是指通过网络爬虫或网站公开API等方式从网站上获取数据信息,该方法可以将半结构化数据、非结构化数据从网页中抽取出来,将其存储为统一的本地数据,支持图片、音频、视频等数据采集。
3.3.1 前置条件
可以搭建以下环境,进行网络爬虫的开发:
- 软件系统:Windows 10/Linux。
- 开发环境:Sublime Text3/PyCharm。
- 数据库:MySQL 5.0+Navicat 10.0.11。
- 编程语言:Python 3.7+Anaconda 4.4。
- 爬虫框架:Scrapy。
- 目标网站:http://blog.jobbole.com/all-posts/。
3.3.2 Scrapy技术原理
Scrapy是一个为爬取网站数据、提取结构化数据而设计的应用程序框架,通常我们可以很简单地通过Scrapy框架实现一个爬虫,抓取指定网站的内容或图片。
Scrapy爬虫完整架构如图3-2所示(此图来源于网络),其中箭头线表示数据流向。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P70_39286.jpg?sign=1739293801-iMJGFOr9YwQH5dGj2FtaoPGGjpZbmZe2-0-ab90720a4d6bed2230bc0a80d00280be)
图3-2 Scrapy架构图
- Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler中间的通信,信号和数据传递等。
- Scheduler(调度器):它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列和入队,当引擎需要时交还给引擎。
- Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses(响应)交还给Scrapy Engine(引擎),由引擎交给Spider来处理。
- Spider(爬虫):它负责处理所有的Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)。
- Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行后期处理(详细分析、过滤、存储等)的地方。
- Downloader Middlewares(下载中间件):一个可以自定义扩展下载功能的组件。
- Spider Middlewares(Spider中间件):一个可以自定义扩展的操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses和从Spider出去的Requests)。
3.3.3 Scrapy新建爬虫项目
(1)安装Scrapy爬虫框架,按WIN+R组合键调出命令行环境,执行如下命令:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P71_39283.jpg?sign=1739293801-jeqUH3yNV6mRhO5uQ0R1ryOFPG6n2iEh-0-f0f02bb46361319e3fc1aa3c0842867e)
(2)按WIN+R组合键调出命令行环境进入根目录Chapter3文件夹下,创建爬虫项目:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P71_39284.jpg?sign=1739293801-dqwMuTDQHuCln8z9wTl6dJMUoGnQkHKA-0-da4492862cd701c08d7e82e68956ca36)
如图3-3所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P71_10617.jpg?sign=1739293801-wYq57f94iyVYMOTMo9QfuLaknTrUIkwA-0-ed8a65a83ab9a68c51f3d30efc45e848)
图3-3 创建BoLeSpider项目
(3)BoLeSpider为项目名称,可以看到将会创建一个名为BoLeSpider的目录,其目录结构大致如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_39282.jpg?sign=1739293801-VjPQlQBQTIh8hg7O7fC4plssHLh32iVS-0-97fb576f2c4055c21612c42d95d04d0b)
下面简单介绍一下主要文件的作用,这些文件分别是:
- scrapy.cfg:项目的配置文件。
- BoLeSpider/:项目的Python模块,将会从这里引用代码。
- BoLeSpider/items.py:项目的目标文件。
- BoLeSpider/pipelines.py:项目的管道文件。
- BoLeSpider/settings.py:项目的设置文件。
- BoLeSpider/spiders/:存储爬虫代码的目录。
(4)在BoLeSpider项目下创建爬虫目录:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_39279.jpg?sign=1739293801-Nx7eFXEJ0Qbxq9SMiwYLiNVsl1KcTSDJ-0-f566e9ad48d26c72a4ca4026d5ec7d08)
如图3-4所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_10755.jpg?sign=1739293801-KGccD1FnZrK40st1hYsQCf85zoswfdWe-0-45226c3ba005ec942b85472d3535a8bc)
图3-4 爬虫目标网站
(5)在同级目录下,执行如下命令,调用爬虫主程序。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_39278.jpg?sign=1739293801-4zMr1LTUg2EYKFYMnEdCbh8lssfufRAU-0-7580b371bd7355cbce52dd6e79531223)
如图3-5所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_10777.jpg?sign=1739293801-PNZzFMD88sHkpJXjAe2hv2XXwLMJjZMH-0-6a3963db49702c5b83a4f103ec3b94fa)
图3-5 运行爬虫项目
(6)在BoLeSpider目录下创建main.py:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_39277.jpg?sign=1739293801-6iXRXpj8hqJOSdpChWHWCJbOddR9XKrq-0-c7dcf3fcb2cd0a23f9245665f4f0c68e)
执行main.py,效果如图3-6所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_10856.jpg?sign=1739293801-lRweBYjXVmUDcukCoHzEeXJEQEwtpDuy-0-88de995bc8662545ac2ed0ba4e09259e)
图3-6 封装main函数运行爬虫项目
main.py中的方法与在命令行环境下scrapy crawl jobbole的执行效果是一致的,之所以单独封装,是为了调试和运行的便利。
3.3.4 爬取网站内容
3.3.3节完成了爬虫项目的构建,接下来主要做4个方面的工作:一是对项目进行相关配置;二是对目标爬取内容分析及提取文本特征信息;三是完成数据爬取工作;四是将数据进行本地化存储。
1. 爬虫项目配置
在做数据爬取工作时,如果不符合爬虫协议爬取工作将会中断。比如遇到404错误页面等情况,爬虫会自动退出。显然,这不符合对爬虫结果的期望,我们希望跳过错误页面继续爬取。因此,为了实现对不符合协议的网页继续爬取,需要打开Scrapy爬虫架构中的setting.py文件进行修改,具体修改如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P74_39276.jpg?sign=1739293801-xHbrXlpKdUe0qiXtTb8qlQNoh7B3nz68-0-147818bc51afd099cee597303ab527e9)
2. 分析爬取的内容
在文章列表http://blog.jobbole.com/all-posts/(实验时可正常访问,目前该官网处于关闭状态,读者重点明白原理及技术细节)中随机打开一篇文章,对单篇文章信息进行分析,并根据需求获取目标数据。假设需要获取文章的【新闻题目、创建时间、URL、点赞数、收藏数、评论数】,如图3-7所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P74_10912.jpg?sign=1739293801-aOGqszCGL0TaYtBrapqzF5lb23kzjP7s-0-deaadc59c4fa9827f091505d00070e63)
图3-7 分析特征数据
3. 爬取文章数据
(1)获取单篇文章的数据有两种方式,分别是基于xpath和CSS的方法。基于xpath的方法操作过程是,使用http://blog.jobbole.com/114638/网址打开单篇文章,按F12键查看源代码,比如想获取文章,可以用光标选中题目的区域,并在右侧用鼠标右键单击源码处,再选中Copy,继续单击“Copy Xpath”。此时的路径为://*[@id="post-114638"]/div[1]/h1,如图3-8所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_10920.jpg?sign=1739293801-TPNFnjn1sPI6DY5pZvPOMmw0nFpH4n6y-0-c1fbcd05ff7ce656622074c98c4c0edc)
图3-8 xpath方法获取数据
(2)在命令行环境下执行以下shell命令:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_39275.jpg?sign=1739293801-bv4jo618CSj4S8yYh4LuEBgMoRf3NOZm-0-d8983ddd8ad3349c95247634b61c2d65)
(3)开始对每个特征进行测试,具体特征数据的测试代码如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_39274.jpg?sign=1739293801-ITVXnhNjewsjbTSfKFj4wspjqmjyzvxf-0-4363724b875d807c2fea0473e4f77550)
(4)完整的特征数据的提取结果如图3-9所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_10969.jpg?sign=1739293801-xgbjQsjNdSOHcHPWhwH2xUZMr6gkrVO5-0-2c47c98ae93bb989b31c5a4ee8ddf68e)
图3-9 测试特征数据提取文本信息
注 意
有时候按照以上方法操作,但却没有提取到文本信息,则有可能是代码错误,请仔细检查代码。也有可能是反爬虫技术的作用,此时,需要登录后再进行数据爬取,这属于更深层次的爬虫技术,本文不再涉及。
(5)使用xpath方法获取数据。
以上逐个特征测试无误后,将代码放在Chapter3/BoLeSpider/BoLeSpider/spiders/jobbole.py文件中的parse方法下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_39271.jpg?sign=1739293801-LRDp9IcrfPpOXNZ7YqsOknuJh4kP9hZq-0-ff2f0212d8046d0fb156d4a4252d0deb)
(6)使用CSS方法获取数据。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P76_39269.jpg?sign=1739293801-hoqygbEGEmiZXoTMkJpw582cG2iGt5Rz-0-c87ee8e1c3887afc43265811f6a6837f)
(7)获取页面信息(源代码见:Chapter3/BoLeSpider/BoLeSpider/spiders/jobbole.py)。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P76_39268.jpg?sign=1739293801-CBzHXYnr9X2UWheBElqDcze9poQqDPxR-0-a89f53a9ca8ae2e8a4073c678ccf8b2d)
(8)运行main.py函数,获取到所有的信息,如图3-10所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P77_11701.jpg?sign=1739293801-Z1c4lIzX9hP2mlIcZb1OYXMbfr0efIdg-0-edb1cf233858e11e6dd78e482d6c10b7)
图3-10 获取单篇文章特征数据
4. 爬取列表页所有文章
(1)实现列表页所有文章信息的爬取工作
按F12键分析网页,找到下一页并获取所有列表页的文章链接。
执行以下代码获取所有列表页的文章链接,如图3-11所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_39266.jpg?sign=1739293801-RB6zXd7dc7HCCiz0YoMgOVcXVfZ2wKzu-0-6114191c15aa1e811be1560791c72302)
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_11742.jpg?sign=1739293801-0uhmuHyjIcEZ29OcTmjcT6hzZChxJdAB-0-1153856cb5351c271cf17917d7269998)
图3-11 获取列表页所有文章的链接
(2)设置目标特征的实体类
打开Scrapy框架内置的Chapter3/BoLeSpider/items.py文件,设计爬虫目标特征的实体类(这里可以将爬虫目标特征的实体类作为数据库操作中实体类来理解)。代码如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_39265.jpg?sign=1739293801-A8I6Ja7GpwTaOfR4GjftGKZyigcKbTW5-0-2a2bf249caee0556a75d9cd9d6c375b1)
(3)修改代码文件jobbole.py
首先将BoLeSpider/spiders/jobbole.py文件的starturls修改为列表页的路径,然后在parse方法中解析文章,并提取下一页交给Scrapy提供下载。parsesdetail方法负责每一篇文章的下载,re_match方法是使用正则表达式对文本信息数据进行处理。完整的代码如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P79_39263.jpg?sign=1739293801-10AoWKv4kXAPJFpkmtqIdyUBlfgEKNvN-0-f1079f79c41d4562d1c233d986c6b46c)
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P80_39262.jpg?sign=1739293801-UMxLnkJa9stoU4HhIufebk0JDgn32IMn-0-fccac138ce3157f2cba7ef2706e4824c)
(4)运行main.py
提取列表页数据,如图3-12所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P81_12634.jpg?sign=1739293801-riHTXcC4sHdNeoabPPbclRUM0RUCtGk9-0-24b9f1275cd749f4b21e28ec1c56a5c5)
图3-12 获取列表页所有文章的特征数据