目录
-
scrapy.cfg: 项目的配置文件
-
tutorial/: 该项目的python模块。之后您将在此加入代码。
-
tutorial/items.py: 项目中的item文件.
-
tutorial/pipelines.py: 项目中的pipelines文件.
-
tutorial/settings.py: 项目的设置文件.
-
tutorial/spiders/: 放置spider代码的目录.
简单入门
创建项目
scrapy startproject tutorial
创建Spider
cd tutorial scrapy genspider quotes quotes.toscrape.com
创建Item
text = scrapy.Field() author = scrapy.Field() tags = scrapy.Field()
解析Response
quotes = response.css('.quote') for quote in quotes: item = QuoteItem() item['text'] = quote.css('.text::text').extract_first() item['author'] = quote.css('.author::text').extract_first() item['tags'] = quote.css('.tags .tag::text').extract() yield item
使用Item
后续Request
next = response.css('.pager .next a::attr(href)').extract_first() url = response.urljoin(next) yield scrapy.Request(url=url, callback=self.parse)
运行
scrapy crawl quotes
保存
json
scrapy crawl quotes -o quotes.json
jsonline
scrapy crawl quotes -o quotes.jl
csv
scrapy crawl quotes -o quotes.csv
xml
scrapy crawl quotes -o quotes.xml
pickle
scrapy crawl quotes -o quotes.pickle
marshal
scrapy crawl quotes -o quotes.marshal
ftp
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv
Item Pipeline的用法
作用
清除HTML数据 验证爬取数据,检查爬取字段 查重并丢弃重复内容 将爬取结果保存到数据库
例子
筛掉text大于50的Item
from scrapy.exceptions import DropItem class TextPipeline(object): def __init__(self): self.limit=50 def process_item(self, item, spider): if item['text']: if len(item['text']) >= self.limit: item['text'] = item['text'][0:self.limit].rstrip() + '....' return item['text'] else: return DropItem('Missing Text')
保存到MongoDB
import pymongo class MongoPipeline(object): def __init__(self, mongo_uri, mongo_db): self.mongo_uri = mongo_uri self.mongo_db = mongo_db # 通过crawler拿到全局配置的每个配置信息 @classmethod def from_crawler(cls, crawler): return cls( mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DB') ) def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = pymongo.MongoClient(self.mongo_db) def process_item(self, item, spider): name = item.__class__.__name__ self.db[name].insert(dict(item)) return item def close_spider(self, spider): self.client.close()
setting
ITEM_PIPELINES = { 'tutorial.pipelines.TextPipeline': 300, 'tutorial.pipelines.MongoPipeline': 400, } MONGO_URI = 'localhost' MONGO_DB = 'tutorial'
核心方法
-
from_crawler(cls,crawler) 通过crawler对象,我们可以拿到Scrapy的核心组件
-
open_spider(spider)
-
process_item(item,spider) 必须要实现的方法,被定义的Item Pipeline会默认调用这个方法对item进行处理
-
close_spider(spider)
Selector的用法
直接使用
body = '<html><head><title>Hello World</title></head></html>' selector=Selector(text=body) title=selector.xpath('//title/text()').extract_first() print(title)
Scrapy shell 在命令行输入 scrapy shell https://doc.scrapy.org/en/latest/_static/selectors-sample1.html response.selector.xpath('//a')
XPath选择器 response.xpath等价于response.selector.xpath
CSS选择器
正则匹配 response.xpath('//a').re('Name:\s(.*)')
Spider的用法
运行流程 要做的事 定义爬取网站的动作 分析爬取下来的网页 爬取循环过程 以初始的url初始化Request,并设置回调函数,当该Request成功请求并返回时,Response生成并作为参数传给回调函数 在回调函数中分析返回的网页内容,返回结果有两种形式,一直是解析到的有效结果返回到字典或Item对象,它们可以经过处理后保存,另一种解析得到下一个链接,可以用此链接构造Request并设置新的回调函数,返回Request等待后续调度 如果返回的是字典或者Item对象,我们可以通过Feed Exports等组件将返回的结果存入到文件,如果设置了Pipeline的话,我们可以使用Pipeline处理并保存 如果返回的是Request,那么Request执行成功得到Response之后,Response会被传递给Request中定义的回调函数,在回调函数中我们可以再次使用选择器来分析新得到的网页内容,并根据分析的数据生成Item
Spider类分析
-
name 爬虫名称
-
allowed_domains 允许爬取的域名
-
custom_settings
-
crawler
-
setting
-
start_requests()
-
parse()
-
close() 当Spider关闭时,该方法会被调用
Downloader Middleware中间下载器
功能
-
修改User-Agent
-
处理重定向
-
设置代理
-
失败重试
-
设置Cookies
核心方法
-
process_request(request,spider)
-
process_response(request,response,spider)
-
process_exception(request,exception,spider)
修改User-Agent
-
修改setting里面的USER_AGENT变量
-
通过Downloader Middleware的process_request方法来修改
修改Response的状态码
通过Downloader Middleware的process_response方法来修改
Spider Middleware的用法
核心方法
-
process_spider_input(request,spider)
-
process_spider_output(response,result,spider)
-
process_spider_exception(response,exception,spider)
-
process_start_requests(start_request,spider)