荐 爬虫进阶之scrapy框架学习
爬虫进阶之scrapy框架学习
前言
爬虫爬来爬去最后都还是用比较主流的框架进行爬取,至于为什么要使用框架进行爬取,可能是基于了Scrapy
框架的以下优点:
- 更容易构建大规模抓取项目;
- 异步处理请求的速度快
- 使用自动调节机制自动调整爬取速度
因此学习爬虫过程中,爬虫框架的学习自然也是重点,萌新第一次接触Scrapy
也发现确实还算比较复杂,因此慢慢总结,尽量能够熟悉一些吧。
正文
什么是Scrapy
框架?
Scrapy
框架是一个快速(fast)、高层次(high-level)的基于Python的web爬虫框架,抓取web站点并从页面提取结构化数据
如何安装创建Scrapy
?
依赖环境:
- Python 2.7及以上
- Python Package: pip and setuptools. 现在 pip 依赖 setuptools ,如果未安装,则会自动安装 setuptools 。
pip install Scrapy
因为scrapy框架基于Twisted,所以先要下载其whl包安装
下载对应Python版本的whl后直接pip install xxxx.whl
即可
在命令提示符中
scrapy startproject [项目名]
会在当前目录下创建一个以项目名
为名的项目架构,以qiushi
为例
qiushi
|--qiushi
|--spiders
|--__init__.py
|--__init__.py
|--items.py
|--middlewares.py
|--pipelines.py
|--settings.py
|--scrapy.cfg
在这里我们首先要对Scrapy
进行架构分析:Scrapy
分为以下几个架构:
- Scrapy Engine:
Scrapy引擎
。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。 - Scheduler:
调度器
。从Scrapy Engine
接受请求(requests)并排序列入队列,并在引擎再次请求时返回。用它来决定下一个抓取的网址是什么,同时去除重复的网址。 - Downloader:下载器。抓取网页并将网页内容返还给Spiders。
建立在twisted异步模型
- Spiders:爬虫。用户自定义的类,主要用来解析网页,提取Items,发送url跟进等新请求等。
- Item Pipelines:管道。主要用来处理Spider解析出来的Items,进行按规则过滤,验证,
持久化存储(如数据库存储)
等 - Downloader Middlewares:下载中间件。位于Scrapy Engine和Downloader之间,主要是处理Scrapy引擎与下载器之间的请求及响应。
- Spider Middlewares:爬虫中间件。位于Scrapy Engine和Spiders之间,主要工作是处理Spiders的响应输入和请求输出。
- Scheduler Middlewares:调度中间件。位于Scrapy Engine和Scheduler之间。主要工作是处理从Scrapy Engine发送到Scheduler的请求和响应。
数据处理流程:
1、引擎打开一个网站(open a domain),找到处理该网站的Spider并向该Spider请求要爬取的第一个start_urls
。
2、引擎从Spider中获取到第一个要爬取的URL
并在调度器(Scheduler)以Request调度。
3、引擎向调度器请求下一个要爬取的URL。
4、调度器返回下一个要爬取的URL给引擎,引擎将URL通过Downloader Middlewares(request)
转发给下载器(Downloader)。
5、一旦页面下载完毕,Downloader生成一个该页面的Response,并将其通过Downloader Middlewares(response)发送给引擎。
6、引擎从Downloader中接收到Response并通过Spider Middlewares(request)发送给Spider处理。
7、Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。
8、引擎将(Spider返回的)爬取到的Item给Item Pipeline
,将(Spider返回的)Request给调度器。
9、系统重复2-9的操作,直到调度中没有更多地request,然后断开引擎与网站之间的联系。
项目实战
萌新第一次接触Scrapy
框架,因此也是跟着其他大佬做过的项目,这次就是简单的爬取糗事百科
的段子和作者,并且分别以data.txt
和author.txt
保存。
先创建项目
scrapy startproject qiushi
这里说明各个文件的作用:
-
scrapy.cfg
:项目的配置文件
,指定settings文件,部署deploy的project名称等等。 -
qimairank
:项目的python模块。 -
spiders
:放置spider代码的目录。 -
items.py
:项目中的item文件。 -
pipelines.py
:项目中的pipelines文件。 -
middlewares.py
:项目的中间件。 -
settings.py
:Scrapy 配置文件。
Xpath学习
学习爬虫,必须先得学会如何利用Xpath
来定位我们所需要找到内容,这里是使用w3school
的案例进行初步的讲解:
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
选取未知节点
开始完善框架内容
创建Item
创建QiushibaikeItem
继承scrapy.Item
,并定义需要存储的作者和内容
创建Spider
在spiders目录下创建qiushi.py
,并创建class QiushiSpider
,继承于Spider。在parse()
用来定义爬虫的爬取规则,并且将爬取的数据给予item
,最后使用关键词yield来进行持久化
def parse(self, response):
div_list = response.xpath('//*[@id="content"]/div')
for div in div_list:
author = div.xpath('.//div[@class="author clearfix"]//h2/text()').extract()
for i in range(len(author)):
author[i] = str(author[i]).replace('\n','')
content = div.xpath('.//div[@class="content"]/span/text()').extract()
for i in range(len(content)):
content[i] = str(content[i]).replace('\n\n','\n')
item = QiushibaikeItem()
for num in range(max(len(content),len(author))):
if(num < len(author)):
item['content'] = content[num]
item['author'] = author[num]
yield item # 提交到item进行持久化
else:
item['content'] = content[num]
item['author'] = None
yield item
if self.page_num <= 13:
self.page_num +=1
url = format(self.url % self.page_num)
yield scrapy.Request(url=url,callback=self.parse) #回调函数重新更改url后进行self.parse操作
//*[@id="content"]/div
选取所有值为content
的id属性的div
子元素//*[@id="content"]/div//div[@class="author clearfix"]/a/h2
即在之前子元素中选择div
中存在值为author clearfix
的class属性的a
子元素的h2
子元素,说起来貌似有点别扭
在创建好以上两个文件后我们应该编辑管道
创建pipelines.py
https://docs.scrapy.org/en/latest/topics/item-pipeline.html
这里是它的文档
可见这是一个接口,必须完成process_item()
这个方法,而这个方法在每一次的yield
中就会调用一次,此外还存在以下两个方法,分别是
在进程开始和结束的时候分别调用一次,是不必须实现的,因此我理解的管道更像是对每一次爬取的item
做出相应的处理,也就是持久化
class QiushibaikePipeline(object):
def __init__(self):
self.fp = None # 定义一个文件描述符属性
self.fp1 = None
def open_spider(self, spider):
print('爬虫开始')
self.fp = open('./data.txt', 'a+')
self.fp1 = open('./author.txt','a+')
def process_item(self, item, spider):
self.fp.write(item['content'])
self.fp1.write(item['author'] + "\n")
return item
def close_spider(self, spider):
self.fp.close()
print('爬虫结束')
这里我分别将文本和作者写在两个txt
文本中
编辑settings.py
最后我们需要编辑其中一些配置,举个例子:
在这个项目中,我们需要设置UA头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。因为现在很多网站有反爬措施,如果没有设置UA头
,此处是没有response.text
项目完成后我们只需要在存在scrapy.cfg
目录下通过cmd
运行爬虫
scrapy crawl qiushi
爬取完毕后会给予相应反馈信息,最后看一下效果如何吧?author.txt
data.txt
总结
目前只学习了框架的初步,还有很多高级功能并没有实践,等以后有时间在多了解了解爬虫的其他框架和Scrapy
的深入学习,自己也应该多实践,争取做一些自己的小项目
本文地址:https://blog.csdn.net/crisprx/article/details/107280110
上一篇: C++ STL迭代器原理和实现