简介
Scrapy 框架
- Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架。
- 用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片。 (提高请求效率)
- Scrapy 使用了Twisted(aiohttp)异步网络框架来处理网络通讯,可以加快下载速度,并且包含了各种中间件接口,可以灵活的完成各种需求。
安装
- pip install --upgrade pip 建议首先更新pip 再安装下列依赖库 否则可能会遇到诸多错误:
2. pip install twisted
安装 twisted可能会遇到这样问题
building 'twisted.test.raiser' extension error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
意思是说缺少C++的一些编译工具
所以这里建议大家直接安装编译好的twisted的whl文件 对应资源下载网址: https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
下载twisted对应版本的whl文件,cp后面是python版本,amd64代表64位
运行命令: pip install C:UsersCRDownloadsTwisted-17.5.0-cp36-cp36m-win_amd64.whl (后边一部分是 whl文件的绝对路径)
3.pip install lxml lxml之前应该安装过 可以略过
4.pip install pywin32 这个安装应该没问题
5.pip install Scrapy 安装scrapy框架
如果中途报错,有TimeOut的字眼,应该是网络问题,重复安装几次就行
当然最省事的还是直接替换安装源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
知识
整体结构
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(爬虫) ——> Spider Middlewares(Spider中间件) ——> Scrapy Engine(引擎) ——> Scheduler(调度器) ——> Scrapy Engine(引擎) ——> Downloader Middlewares(下载中间件) ——> Downloader(下载器) ——> Downloader Middlewares(下载中间件) ——> Scrapy Engine(引擎) ——> Spider Middlewares(Spider中间件) ——> Spider(爬虫) ——> Spider Middlewares(Spider中间件) ——> Item Pipeline(管道)
Scrapy完成爬虫需要涉及的文件和步骤
- 新建项目 (scrapy startproject xxx):新建一个新的爬虫项
- 明确目标(编写items.py):明确你想要抓取的目标
- 制作爬虫(spiders/xxspider.py):制作爬虫开始爬取网页
- 存储内容(pipelines.py):设计管道存储爬取内容
入门案例
项目创建
执行: 终端输入代码:scrapy startproject JobSpider
结果: 目录结构:
确定目标
确定要爬取的网站和信息的url
抓取上海地区python招聘职位的情况,包括职位名称,公司名称,工作地点,薪资,发布时间:
目标地址: https://search.51job.com/list/020000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare
1.打开项目中的item.py文件
2.创建一个JobspiderItem类,继承scrapy.Item,构建item模型(model)。并且定义类型为scrapy.Field的类属性,用来保存爬取到的数据
class JobspiderItem(scrapy.Item):
name = scrapy.Field()
city = scrapy.Field()
pub_date = scrapy.Field()
salary = scrapy.Field()
制作爬虫
生成爬虫脚本模板
执行: 终端输入代码: 1.cd JobSpider
2.scrapy genspider pythonPosition http://51job.com
结果:
脚本说明
打开上一步生成的模板
import scrapy
class PythonpositionSpider(scrapy.Spider):
name = 'PythonPosition'
allowed_domains = ['51job.com']
start_urls = ['http://51job.com/',]
def parse(self, response):
pass
说明:
1.name="":这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
2.allow_domains=[]是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
3.start_urls=():爬取的URL元祖/列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。
4.parse(self,response):解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,主要作用如下: 负责解析返回的网页数据(response.body),提取结构化数据(生成item) 生成需要下一页的URL请求。
修改代码
# 1.将start_urls的值修改为需要爬取的第一个url
start_urls=("https://search.51job.com/list/020000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=",)
# 2.重写parse方法,用XPath提取数据
def parse(self, response):
#print(response.body)
job_list = response.xpath("//div[@class='dw_table']/div[@class='el']")
for each in job_list:
name = each.xpath("normalize-space(./p/span/a/text())").extract()[0]
city = each.xpath("./span[@class='t3']/text()").extract()[0]
pub_date = each.xpath(".//span[@class='t5']/text()").extract()[0]
salary = each.xpath(".//span[@class='t4']/text()").extract()
if len(salary)>0:
salary = salary[0]
else:
salary = ''
item = JobspiderItem()
item['name'] = name
item['city'] = city
item['pub_date'] = pub_date
item['salary'] = salary
# 将获取的数据交给pipeline
yield item
yield 不仅可以返回数据对象,也可以返回请求对象。
储存内容
打开存储管道文件:
process_item 方法是用来处理每一个item数据对象的 close_spider 关闭爬虫时调用
# 写入CSV文件:
import csv
import codecs
class JobspiderPipeline(object):
def __init__(self):
self.file = codecs.open('51job.csv', 'w', 'utf-8')
self.wr = csv.writer(self.file, dialect="excel")
self.wr.writerow(['name', 'pub_date', 'city', 'salary'])
def process_item(self, item, spider):
self.wr.writerow([item['name'], item['pub_date'], item['city'], item['salary']])
return item
def close_spider(self, spider):
self.file.close()
在setting文件中启动储存管道
启用一个Item Pipeline组件
为了启用Item Pipeline组件,必须将它的类添加到settings.py文件ITEM_PIPELINES 配置,比如:
ITEM_PIPELINES = {
#'mySpider.pipelines.SomePipeline': 300,"
mySpider.pipelines.JsonPipeline":300
}
分配给每个类的整型值,确定了他们运行的顺序,item按数字从低到高的顺序通过pipeline,通常将这些数字定义在0-1000范围内(0-1000随意设置,数值越低,组件的优先级越高)
运行测试
1、创建run.py文件,和setting.py同级目录
2、添加代码:
from scrapy import cmdline
# 其中name参数为spider的name。
name = 'pythonPosition' cmd = 'scrapy crawl {0}'.format(name)
scrapy crawl pythonPosition
cmdline.execute(cmd.split())
3、run.py文件中右键运行。
任务
使用scrapy完成豆瓣电影top 250爬虫,电影的名称,简介,评分,引文等信息采集 https://movie.douban.com/top250?start=0&filter=2