CrawlSpider详解与动手实例(微信小程序社区)
CrawlSpider相比于scrapy的强大之处就是之前的爬虫如果爬完一页了要去爬取第二页的数据需要自己yield发送请求过去,而CrawlSpider就只需要指定一些规则,满足规则的url就去下载,不满足的就不下载。
crawlspider中两个图书的类LinkExtractors、Rule
-
LinkExtractors链接提取器
程序员可以提取想要的url,然后发出请求。这些工作都可以交给LinkExtractors,他会在所有爬取的页面中找到满足规则的url,实现爬取.主要参数(常用)
allow - 一个单一的正则表达式(或正则表达式列表),(绝对)urls必须匹配才能提取。如果没有给出(或为空),它将匹配所有链接。
deny) - 一个正则表达式(或正则表达式列表),(绝对)urls必须匹配才能排除(即不提取)。它优先于allow参数。如果没有给出(或为空),它不会排除任何链接。
allow_domains(str或list) - 单个值或包含将被考虑用于提取链接的域的字符串列表
deny_domains(str或list) - 单个值或包含不会被考虑用于提取链接的域的字符串列表
restrict_xpaths(str或list) - 是一个XPath(或XPath的列表),它定义响应中应从中提取链接的区域。如果给出,只有那些XPath选择的文本将被扫描链接。参见下面的例子。
-
Rule 规则类
定义爬虫的规则类,主要参数:
link_extractor:一个LinkExtractors,用于定义爬起规则
callback:满足这个规则url,应该执行哪个回调函数.(如果只是用来列表页可以设置回调函数)
follow:指定根据规则从response中提取的链接是否需要跟进
process_links:从link_extractor中获取到的链接后会传递给这个函数,用来过滤不需要爬取的链接
- 创建scrapy项目
scrapy startproject XX - 创建crwal spider
scrapy genspider -t crawl Name 域名 - 修改rule规则
Rule(LinkExtractor(allow=r'http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=\d'), follow=True),
#无callback说明不需要对获取到的页面进行操作,follow=true说明要提取所有对应要求的url列表
Rule(LinkExtractor(allow=r'.+article-.+\.html'), callback='parse_detail',follow=False),
#有callback说明需要对获取到的页面进行操作,follow=False说明不要提取所有对应要求的url列表
- 其余scrapy操作正常
- 启动scrapy crawl name
使用CrawlSpider爬取微信小程序社区 - 创建scrapy项目:scrapy startproject weixinapp
- 创建crawlspider爬虫:scrapy genspider -t crawl wxapp_spider www.wxapp-union.com
- 配置crawlspider的rule规则和回调函数
class WxappSpiderSpider(CrawlSpider):
name = 'wxapp_spider'
allowed_domains = ['www.wxapp-union.com']
start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1']
rules = (
#注意正则表达式中的转义\. \+ \?
Rule(LinkExtractor(allow=r'.+mod=list&catid=2&page=\d'), follow=True),
#无callback说明不需要对获取到的页面进行操作,follow=true说明要提取所有对应要求的url列表
Rule(LinkExtractor(allow=r'.+article-.+\.html'), callback='parse_detail',follow=False),
#有callback说明需要对获取到的页面进行操作,follow=False说明不要提取所有对应要求的url列表
)
def parse_detail(self, response):
title = response.xpath('//h1[@class="ph"]/text()').get()
author = response.xpath('//a[@href="space-uid-17761.html"]/text()').get()
time = response.xpath('//span[@class="time"]/text()').get()
artical_content = response.xpath('//td[@id="article_content"]//text()').getall()
artical_content = ''.join(artical_content).strip()
item = WeixinappItem(title=title, author=author, time=time, content=artical_content)
yield item
- 配置item文件
class WeixinappItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
author = scrapy.Field()
time = scrapy.Field()
content = scrapy.Field()
- 配置pipeline文件
class WeixinappPipeline(object):
def __init__(self):
self.f = open("weixin.json", "wb")
def process_item(self, item, spider):
content = json.dumps(dict(item), ensure_ascii=False) + ",\n"
self.f.write(content.encode('utf-8'))
return item
def close_spider(self, spider):
self.f.close()
- 配置setting文件
- 启动:scrapy crawl wxapp_spider