![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=1739275972-JRczNYIFacwus4AMZuP1KABzDcOElevK-0-48395119408b6f3b30b8785b41e5f996)
图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=1739275972-5qga9VQVTrub5dPwFxCB32FvEsPpFmTn-0-d9124fcf2165e195d4ee8ac654b560b7)
(2)按WIN+R组合键调出命令行环境进入根目录Chapter3文件夹下,创建爬虫项目:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P71_39284.jpg?sign=1739275972-l6C4VQjErzbbT7WvbTZyUc8qYm7m7LD4-0-15788cf2365841ceb74ca1cc4bd5cb81)
如图3-3所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P71_10617.jpg?sign=1739275972-65uSjOlLsDAbsk02bFjI6djIuCdJEmll-0-cacf5938d6412664ec30d4df29d8076a)
图3-3 创建BoLeSpider项目
(3)BoLeSpider为项目名称,可以看到将会创建一个名为BoLeSpider的目录,其目录结构大致如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_39282.jpg?sign=1739275972-k1CGeumBviFUNAULMnMcK1zItI3i3trN-0-09f4bd1ec6586dd08be71884f9ac8794)
下面简单介绍一下主要文件的作用,这些文件分别是:
- 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=1739275972-z4oPBCyvgesluoM45AWM0D63u5wliU0F-0-1859f2044737b4dd86042f9a9402e188)
如图3-4所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_10755.jpg?sign=1739275972-JVToDyViRbvhXPiQqeQDuQeB4FK2M50P-0-161bdad76dd8d9351ed87271f81f40bc)
图3-4 爬虫目标网站
(5)在同级目录下,执行如下命令,调用爬虫主程序。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P72_39278.jpg?sign=1739275972-YUpVsK60gyInhjuPCcJpH3A4YTecZkRq-0-a571d9d6f312db74d50dbc53f677142d)
如图3-5所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_10777.jpg?sign=1739275972-SO2AtQ50GaRoqHGljl6DFfRXbbwysTiL-0-639cc3c942e1bd45ae51044284699a3f)
图3-5 运行爬虫项目
(6)在BoLeSpider目录下创建main.py:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_39277.jpg?sign=1739275972-2uuutizvM8fHMxGvA4RPcXyeIr4kH8ci-0-792db440920edab30abade8224cb0be8)
执行main.py,效果如图3-6所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P73_10856.jpg?sign=1739275972-UXTbc7HY3C3zFpQTsuzW6gwBZiql3IFq-0-cdf42b629c2d11a4cbcf292d3ad9c62e)
图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=1739275972-f4rX5mQ27vRH8cHun6kto8cIMSRGWKyz-0-47c31a064f5cf9c3025af577cd8d723e)
2. 分析爬取的内容
在文章列表http://blog.jobbole.com/all-posts/(实验时可正常访问,目前该官网处于关闭状态,读者重点明白原理及技术细节)中随机打开一篇文章,对单篇文章信息进行分析,并根据需求获取目标数据。假设需要获取文章的【新闻题目、创建时间、URL、点赞数、收藏数、评论数】,如图3-7所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P74_10912.jpg?sign=1739275972-HborGHUxjSU8lu0ElJWkwfnVTKUc9b2F-0-24fda01fa8a7466254f7eaefeccc32ca)
图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=1739275972-KgwfAH31gnX4bk5EWSoMSbgBFv4KspLV-0-db21e8b31ffc0a8c871b14856b261e7d)
图3-8 xpath方法获取数据
(2)在命令行环境下执行以下shell命令:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_39275.jpg?sign=1739275972-tKhKjjfpH5QjLGU0X1Q8kimbEWHe6Ggd-0-ecc47d3de667c95e86f5dce5d345d895)
(3)开始对每个特征进行测试,具体特征数据的测试代码如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_39274.jpg?sign=1739275972-rDmYjnlOq9UrZuGnglhtodKiWoNstDwu-0-c910e248725d371627266f7cb916bcbf)
(4)完整的特征数据的提取结果如图3-9所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P75_10969.jpg?sign=1739275972-UEq7rc2QRhgOZ8CUyA7EjEt4Z0AQO0s5-0-4fce344ea582d35924c9a749eec7479c)
图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=1739275972-5K0Wm8UfDwVMbhUCK9BRC4RXFDspFCeJ-0-d05639222a0ebb3836f3ae03ef04e80a)
(6)使用CSS方法获取数据。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P76_39269.jpg?sign=1739275972-5BpIeuewrDwSpQtSCDL3lmxre35E9CrS-0-fd1438cb84df3288c25b5d709c0de069)
(7)获取页面信息(源代码见:Chapter3/BoLeSpider/BoLeSpider/spiders/jobbole.py)。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P76_39268.jpg?sign=1739275972-QRH4kM8zW6eMiwq5VxtgoDJP7R0VXxxH-0-2bbc97c49200e89f42834922cfc27739)
(8)运行main.py函数,获取到所有的信息,如图3-10所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P77_11701.jpg?sign=1739275972-4cqU3dkK8DMJ3AKOebqyzgq4cdOF6x0P-0-b44e7c68836022b4b3731908c8dc8f62)
图3-10 获取单篇文章特征数据
4. 爬取列表页所有文章
(1)实现列表页所有文章信息的爬取工作
按F12键分析网页,找到下一页并获取所有列表页的文章链接。
执行以下代码获取所有列表页的文章链接,如图3-11所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_39266.jpg?sign=1739275972-pTu1006wUeFWl8C14aUMKaJ3J5xYV3yN-0-9d4a5d201d929853b0cc17ec39381366)
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_11742.jpg?sign=1739275972-PbivWWYx5Aeb3sYhqCYwkKT20hs8XhnU-0-4feeaa6bf53c5e1d9d50edd06460f9f0)
图3-11 获取列表页所有文章的链接
(2)设置目标特征的实体类
打开Scrapy框架内置的Chapter3/BoLeSpider/items.py文件,设计爬虫目标特征的实体类(这里可以将爬虫目标特征的实体类作为数据库操作中实体类来理解)。代码如下:
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P78_39265.jpg?sign=1739275972-rEzLssjKga8Fycere81oG4hdC4wCA6f0-0-6967514be3346f2b27409ef9339359ef)
(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=1739275972-T38Cjbc54fSURRX1pfHeoh8CUR2oNF6W-0-f566338dbb094e149648b5fdd14225e7)
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P80_39262.jpg?sign=1739275972-uPywHQ6NaUzhThXJVVkEg8h9JTTayyPZ-0-154c9c2ea1f23490d6f7c7f6618ade6e)
(4)运行main.py
提取列表页数据,如图3-12所示。
![](https://epubservercos.yuewen.com/FBFBF6/15825992205221306/epubprivate/OEBPS/Images/Figure-P81_12634.jpg?sign=1739275972-E4eCco0ALxPHEexFLvNUJVs4cn1VhtFc-0-6f0801777e0779fd52686b9cce9b3c9a)
图3-12 获取列表页所有文章的特征数据