之前的代码中,我们有很⼤⼀部分时间在寻找下⼀⻚的URL地址或者内容的URL地址上⾯,这个过程能更简单⼀些吗?
思路:
- 从response中提取所有的
a
标签对应的URL地址- 自动的构造自己resquests请求,发送给引擎
生成crawlspider
的命令:scrapy genspider -t crawl 爬虫名字 域名
LinkExtractors链接提取器
使用LinkExtractors可以不用程序员自己提取想要的url,然后发送请求.这些工作都可以交给LinkExtractors,他会在所有爬的页面中找到满足规则的url,实现自动的爬取
class scrapy.linkextractors.LinkExtractor(
allow = (),
deny = (),
allow_domains = (),
deny_domains = (),
deny_extensions = None,
restrict_xpaths = (),
tags = ('a','area'),
attrs = ('href'),
canonicalize = True,
unique = True,
process_value = None
)
主要参数讲解:
- allow:允许的url,所有满足这个正则表达式的url都会被提取
- deny:禁止的url.所有满足这个正则表达式的url都不会被提取
- allow_domains:允许的域名.只有在这个里面指定的域名的url才会别提取
- deny_domains:禁止的域名.所有在这个里面指定的域名的url都不会被提取
- restrict_xpaths:严格的xpath.和allow共同过滤链接
Rule规则类
定义爬虫的规则类
class scrapy.spider.Rule(
link_extractor=None,
callback=None,
cb_kwargs=None,
follow=None,
process_links=None,
process_request=None
)
主要参数讲解:
- link_extractor:一个LinkExtractor对象,用于定义爬取规则
- callback:满足这个规则的url,应该要执行哪个回调函数,因为
CrawlSpider
使用了parse作为回调函数,因此不要覆盖parse作为回调函数自己的回调函数 - follow:指定根据该规则从response中提取的链接是否需要跟进
- process_links:从link_extractor中获取到链接后会传递给这个函数,用来过滤不需要爬取的链接
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class CygSpider(CrawlSpider):
name = "cyg"
allowed_domains = ["wz.sun0769.com"]
start_urls = ["https://wz.sun0769.com/political/index/politicsNewest?id=1&page=1"]
rules = (
# 列表页
# 使用正则表达式 \d 匹配数字
Rule(LinkExtractor(allow=r"wz\.sun0769\.com\/political\/index\/politicsNewest\?id=1\&page=\d+"), follow=True),
# 详情页
Rule(LinkExtractor(allow=r"wz\.sun0769\.com\/political\/politics\/index\?id=\d+"),callback='parse_item'),
)
def parse_item(self, response):
item = {}
item['content'] = response.xpath("//div[@class='details-box']/pre/text()").extract_first()
print(item)
return item
注意点:
-
⽤命令创建⼀个crawlspider的模板:scrapy genspider -t crawl <爬⾍名字><all_domain>,也可以⼿动创建
-
CrawlSpider中不能再有以parse为名字的数据提取⽅法,这个⽅法被CrawlSpider⽤来实现基础URL提取等功能
-
⼀个Rule对象接受很多参数,⾸先第⼀个是包含URL规则的LinkExtractor对象,常⽤的还有callback和follow
- callback:连接提取器提取出来的URL地址对应的响应交给他处理
- follow:连接提取器提取出来的URL地址对应的响应是否继续被rules来过滤
-
不指定callback函数的请求下,如果follow为True,满⾜该rule的URL还会继续被请求
-
如果多个Rule都满⾜某⼀个URL,会从rules中选择第⼀个满⾜的进⾏操作