目录:Python网络爬虫实战系列
- Python网络爬虫实战之一:网络爬虫理论基础
- Python网络爬虫实战之二:环境部署、基础语法、文件操作
- Python网络爬虫实战之三:基本工具库urllib和requests
- Python网络爬虫实战之四:BeautifulSoup
- Python网络爬虫实战之五:正则表达式
- Python网络爬虫实战之六:静态网页爬取案例实战
- Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS
- Python网络爬虫实战之八:动态网页爬取案例实战 Selenium + Headless Chrome
- Python网络爬虫实战之九:Selenium进阶操作与爬取京东商品评论
- Python网络爬虫实战之十:利用API进行数据采集
- Python网络爬虫实战之十一:Scrapy爬虫框架入门介绍
- Python网络爬虫实战之十二:Scrapy爬虫三个实战小案例
- Python网络爬虫实战之十三:Scrapy爬取名侦探柯南漫画集
- Python网络爬虫实战之十四:Scrapy结合scrapy-splash爬取动态网页数据
正文:
一、Scrapy简介
Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv、json等文件中。它能我们更好的完成爬虫任务,自己写Python爬虫程序好比孤军奋战,而使用了Scrapy就好比手底下有了千军万马。
- Scrapy Engine(Scrapy核心) 负责数据流在各个组件之间的流。
- Spiders(爬虫)发出Requests请求,经由Scrapy Engine(Scrapy核心) 交给Scheduler(调度器),Downloader(下载器)Scheduler(调度器) 获得Requests请求,然后根据Requests请求,从网络下载数据。
- Downloader(下载器)的Responses响应再传递给Spiders进行分析。根据需求提取出Items,交给Item Pipeline进行下载。Spiders和Item Pipeline是需要用户根据响应的需求进行编写的。
- 除此之外,还有两个中间件,Downloaders Mddlewares和Spider Middlewares,这两个中间件为用户提供方面,通过插入自定义代码扩展Scrapy的功能,例如去重等。
二、安装Scrapy
方法一,pip install scrapy
方法二,在http://www.lfd.uci.edu/~gohlke/pythonlibs/下载好对应自己Python版本的库,然后通过pip install XX库名 或 python setup.py install 安装。
安装Scrapy需要的库有:wheel、lxml、Twisted、Scrapy、pywin32
三、第一个Scrapy爬虫
1、创建项目
在开始爬取之前,您必须创建一个新的Scrapy项目。 进入您打算存储代码的目录中,运行下列命令
scrapy startproject tutorial
该命令将会创建包含下列内容的 tutorial 目录:
- scrapy.cfg: 项目的配置文件
- tutorial/: 该项目的python模块。之后您将在此加入代码。
- tutorial/items.py: 项目中的item文件.
- tutorial/middlewares.py:项目中的中间件
- tutorial/pipelines.py: 项目中的pipelines文件.
- tutorial/settings.py: 项目的设置文件.
- tutorial/spiders/: 放置spider代码的目录.
2、编写Spider
Spider是用户编写用于从单个网站(或者一些网站)爬取数据的类,创建一个Spider,必须继承 scrapy.Spider 类, 且定义以下三个属性:name、start_urls、parse()
tutorial/spiders 目录下的新建 csdn_spider.py 文件,代码如下:
import scrapy
class CsdnSpider(scrapy.Spider):
name = "csdn"
allowed_domains = ["csdn.net"]
start_urls = [
"https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
"https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
]
def parse(self, response):
filename = "D:/DataguruPyhton/PythonSpider/images/" + response.url.split("/")[-1] + ".txt"
with open(filename, 'wb') as f:
f.write(response.body)
- name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
- start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
- parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
3、爬取
进入项目的根目录,执行下列命令启动Spider
scrapy crawl csdn
运行结果是生成了两个文件 79436956.txt 和 81463841.txt
刚才发生了什么?
Scrapy为Spider的 start_urls 属性中的每个URL创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了Request。
Request对象经过调度,执行生成 scrapy.http.Response 对象并送回给spider parse() 方法。
四、第二个Scrapy爬虫
1、Scrapy Selectors机制
从网页中提取数据有很多方法,Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。
这里给出XPath表达式的例子及对应的含义:
- /html/head/title: 选择HTML文档中 标签内的
元素 - /html/head/title/text(): 选择上面提到的
元素的文字 - //td: 选择所有的 td 元素
- //div[@class="mine"]: 选择所有具有 class="mine" 属性的 div 元素
上边仅仅是几个简单的XPath例子,XPath实际上要比这远远强大的多。
2、在Shell中尝试Selector选择器
为了配合XPath,Scrapy除了提供了 Selector 之外,还提供了方法来避免每次从response中提取数据时生成selector的麻烦。Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):
- xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。
- css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.
- extract(): 序列化该节点为unicode字符串并返回list。
- re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。
为了介绍Selector的使用方法,接下来我们将要使用内置的 Scrapy shell 。Scrapy Shell需要您预装好IPython(一个扩展的Python终端)。
您需要进入项目的根目录,执行下列命令来启动shell:
scrapy shell "https://blog.csdn.net/jiangwei0910410003/article/details/79436956"
观察终端的输出信息。
当shell载入后,您将得到一个包含response数据的本地 response 变量。输入 response.body 将输出response的包体, 输出 response.headers 可以看到response的包头。
更为重要的是,当输入 response.selector 时, 您将获取到一个可以用于查询返回数据的selector(选择器), 以及映射到 response.selector.xpath() 、 response.selector.css() 的 快捷方法(shortcut): response.xpath() 和 response.css() 。
同时,shell根据response提前初始化了变量 sel 。该selector根据response的类型自动选择最合适的分析规则(XML vs HTML)。
在Shell中尝试如下操作:
In [1]: response.xpath('//title')
Out[1]: [Open Directory - Computers: Progr'>]
In [2]: response.xpath('//title').extract()
Out[2]: [u'Open Directory - Computers: Programming: Languages: Python: Books ']
In [3]: response.xpath('//title/text()')
Out[3]: []
In [4]: response.xpath('//title/text()').extract()
Out[4]: [u'Open Directory - Computers: Programming: Languages: Python: Books']
In [5]: response.xpath('//title/text()').re('(\w+):')
Out[5]: [u'Computers', u'Programming', u'Languages', u'Python']
3、编写新的Spider
import scrapy
class CsdnSpider(scrapy.Spider):
name = "csdn"
allowed_domains = ["csdn.net"]
start_urls = [
"https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
"https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
]
def parse(self, response):
for sel in response.xpath('//*[@id="asideProfile"]'):
author = sel.xpath('div[1]/div[2]/p[1]/a/text()').extract()
fans = sel.xpath('div[2]/dl[2]/dd/span/text()').extract()
like = sel.xpath('div[2]/dl[3]/dd/span/text()').extract()
comment = sel.xpath('div[2]/dl[4]/dd/span/text()').extract()
print(author, fans, like, comment)
4、爬取
进入项目的根目录,执行下列命令启动Spider
scrapy crawl csdn
五、使用了Item的Scrapy爬虫
1、定义Item
Item 是保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。
类似在ORM中做的一样,您可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个Item。 (如果不了解ORM, 不用担心,您会发现这个步骤非常简单)
首先根据需要从csdn.net获取到的数据对item进行建模。 我们需要从csdn中获取作者名字、粉丝数量、喜欢数量、评论数量。 对此,在item中定义相应的字段。编辑 tutorial 目录中的 items.py 文件:
import scrapy
class CsdnItem(scrapy.Item):
author = scrapy.Field()
fans = scrapy.Field()
like = scrapy.Field()
comment = scrapy.Field()
2、编写新的Spider
import scrapy
from tutorial.items import CsdnItem
class CsdnSpider(scrapy.Spider):
name = "csdn"
allowed_domains = ["csdn.net"]
start_urls = [
"https://blog.csdn.net/jiangwei0910410003/article/details/79436956",
"https://blog.csdn.net/M7720EIoSi6oA9/article/details/81463841"
]
def parse(self, response):
for sel in response.xpath('//*[@id="asideProfile"]'):
item = CsdnItem()
item['author'] = sel.xpath('div[1]/div[2]/p[1]/a/text()').extract()
item['fans'] = sel.xpath('div[2]/dl[2]/dd/span/text()').extract()
item['like'] = sel.xpath('div[2]/dl[3]/dd/span/text()').extract()
item['comment'] = sel.xpath('div[2]/dl[4]/dd/span/text()').extract()
yield item
3、爬取
进入项目的根目录,执行下列命令启动Spider
scrapy crawl csdn
4、保存爬取到的数据到csdn_item.json
最简单存储爬取的数据的方式是使用 Feed exports(进入项目的根目录,执行下列命令启动Spider):
scrapy crawl csdn -o csdn_item.json
该命令将采用 JSON 格式对爬取的数据进行序列化,生成 csdn_item.json 文件。
在类似本篇教程里这样小规模的项目中,这种存储方式已经足够。 如果需要对爬取到的item做更多更为复杂的操作,您可以编写 Item Pipeline 。 类似于我们在创建项目时对Item做的,用于您编写自己的 tutorial/pipelines.py 也被创建。 不过如果您仅仅想要保存item,您不需要实现任何的pipeline。