Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下:
一、安装
#Windows平台 1、pip install wheel #安装后,便支持通过wheel文件安装软件,wheel文件官网:https://www.lfd.uci.edu/~gohlke/pythonlibs 2、pip install lxml 3、pip install pyopenssl 4、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/ 5、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 6、执行pip install 步骤5中下载的文件路径 7、pip install scrapy #Linux平台 1、pip install scrapy
二、命令行工具
主要有两种命令:其中Project-only必须切到项目文件夹下才能执行,而Global的命令则不需要。具体介绍如下:
#1 查看帮助 scrapy -h scrapy <command> -h #2 两种命令 Global commands: #确保切换到项目所建目录下 startproject #创建项目,如:scrapy startproject myProject genspider #创建爬虫程序,如:cd myProject; scrapy genspider baidu(程序名) http://www.baidu.com(url) settings #如果是在项目目录下,则得到的是该项目的配置 runspider #运行一个独立的python文件,不必创建项目 shell #scrapy shell url地址 在交互式调试,如选择器规则正确与否 fetch #独立于程单纯地爬取一个页面,可以拿到请求头 view #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求 version #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本 Project-only commands: crawl #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False check #检测项目中有无语法错误 list #列出项目中所包含的爬虫名 edit #编辑器,一般不用 parse #scrapy parse url地址 --callback 回调函数 #以此可以验证我们的回调函数是否正确 bench #scrapy bentch压力测试 #3 官网链接 https://docs.scrapy.org/en/latest/topics/commands.html
命令应用实例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#1、执行全局命令:请确保不在某个项目的目录下,排除受该项目配置的影响 scrapy startproject MyProject cd MyProject scrapy genspider baidu www.baidu.com scrapy settings --get XXX #如果切换到项目目录下,看到的则是该项目的配置 scrapy runspider baidu.py scrapy shell https://www.baidu.com response response.status response.body view(response) scrapy view https://www.taobao.com #如果页面显示内容不全,不全的内容则是ajax请求实现的,以此快速定位问题 scrapy fetch --nolog --headers https://www.taobao.com scrapy version #scrapy的版本 scrapy version -v #依赖库的版本 #2、执行项目命令:切到项目目录下 scrapy crawl baidu scrapy check scrapy list scrapy parse http://quotes.toscrape.com/ --callback parse scrapy bench
三、应用实例
爬取汽车之家咨询新闻:
spider文件代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# -*- coding: utf-8 -*- import scrapy from scrapy.selector import HtmlXPathSelector,Selector from scrapy.http import Request from ..items import Project1Item class AutohomeSpider(scrapy.Spider): name = 'autoHome' allowed_domains = ['www.autohome.com.cn'] offset = 1 url='http://www.autohome.com.cn/all/' start_urls = [url+str(offset)+'/'] def parse(self, response): ''' 三种使用xpath方式 (1)response.xpath() from scrapy.selector import Selector (2)hxs = Selector(response=response) from scrapy.selector import HtmlXPathSelector (3)hxs = HtmlXPathSelector(response) hxs.xpath()或者hxs.select() ''' hxs=HtmlXPathSelector(response) news_list=hxs.select('//ul[@class="article"]/li') for item in news_list: title=item.xpath('.//h3/text()').extract_first() url=item.xpath('.//a/@href').extract_first() abstract=item.xpath('.//p/text()').extract_first() # print(title,url,abstract) yield Project1Item(title=title,url=url,abstract=abstract) while self.offset<5000: #循环爬取其他页码 self.offset+=1 yield Request(url=self.url+str(self.offset)+'/',callback=self.parse)
items文件代码:
import scrapy class Project1Item(scrapy.Item): url=scrapy.Field() title=scrapy.Field() abstract=scrapy.Field()
pipleline文件代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json class Project1Pipeline(object): def process_item(self, item, spider): # 操作并进行持久化,此函数必须有 text=json.dumps(dict(item),ensure_ascii=False)+' ' #存入json形式内容 self.f.write(text) return item # return表示会被后续的pipeline继续处理 # 表示将item丢弃,不会被后续pipeline处理 # raise DropItem() def open_spider(self, spider): """ 爬虫开始执行时,调用。也可定义个__init__函数代替 :param spider: :return: """ self.f = open('autohome.json', 'w+', encoding='utf-8') def close_spider(self, spider): """ 爬虫关闭时,被调用 :param spider: :return: """ self.f.close()
pipleline代码主要是用于做持久化用。要使其起作用,必须在setting文件中设置此中间件。如下例:ITEM_PIPELINES = {'project1.pipelines.Project1Pipeline': 300,},数字表示中间件的优先级,数字越小,优先级就会越高。
注意:默认只能在终端执行爬虫程序,想要在pycharm中执行爬虫文件,需要定义如下文件,然后直接在pycharm中执行此文件即可:
#在项目目录下新建:entrypoint.py from scrapy.cmdline import execute execute(['scrapy', 'crawl', 'autoHome'])