最近在学习爬虫,对于crawlspider rules的运行机制有点疑问,于是自己研究了一下,总结出以下几点:
1、rules里的Rule规则运行是有顺序的,按照由上往下执行;
2、request url的获取是Rule定位到的容器里,所有a标签里的href链接,比如用xpath定位
rules = (
Rule( Extractor(restrict_xpaths=(\"//div/ul\")),callback=\'parse_item\'),
)
则在ul容器下的所有a标签的链接全都会被获取到,并且侍自动发送请求,不用自己手动发送请求;
3、响应页面是Rule请求的链接的页面内容,也就是你定位容器ul里的a标签的链接,然后你用鼠标点击该链接所看到的页面内容,在callback函数里提取数据也是在这个页面里提取,parse_item(self,response),这个函数的response对象就是这个页面内容,千万不要搞错对象了;
4、follow,这个参数开始把我搞得有点晕,follow就是跟进的意思,如果follow=True,那么,在你获取到的响应页面里,所以符合Rule规则的href链接都会被获取到,而且它还会自动跟进,进入到获取到的链接响应页面,在该页面又一次匹配Rule规则,看看有没有符合的,如果有又继续跟进,一直到匹配不到规则为止。举个例子:
rules = (
Rule( Extractor(restrict_xpaths=(\"//div/ul\")),follow=True),
)
那么首先,该规则会获取当前页面符合Rule规则的所有a链接,当前页面就是start_urls页面,比如获取到的链接为
<a class=\'dd_first \' href=\"http://book.dangdang.com/textbook?biaoti\" target=\"_blank\" =\"教材\" nname=\"book-65152-9163_1-468598_2\" ddt-src=\"http://book.dangdang.com/textbook?biaoti\">教材</a>
它会继续进入这个href链接的页面,然后继续再匹配Rule规则,看看还有没有符合的链接,就相当于你在响应页面的elements里面查找到符合规则的a标签url之后,再点击这个url,再在这个页面的elements里查找还有没有符合Rule规则的href链接,如此循环,直到找不到符合Rule规则为止;
5、如果Rule规则里有callback=\"parse_item\",follow=True,那么情况就会比较复杂,你可以想像获取到一个响应页面符合Rule规则的链接,然后调用函数,在这个页面再去follow其它的目标链接,再调用函数,用xpath定位会相对好一点,如果用allow=(r\'\')正则表达式匹配,会相对混乱点,适当的情况下也会这样子用,但是比较少吧,可以自己测试体验一下。
6、翻页,翻页有两种情况
第一种情况(start_url的响应页面下方有翻页链接):
在rules里定义两条Rule规则,一条是获取响应页面规则,一条是获取翻页链接规则,翻页的规则跟在获取响应页面规则下面,顺序不要搞错了,如下:
rules = (
Rule( Extractor(allow=r\'/web/site0/tab5240/info\\d+\\.htm\'), callback=\'parse_item\'),
Rule( Extractor(allow=r\'http://bxjg.circ.gov.cn/web/site0/tab5240/module14430/page\\d\\.htm\'),follow=True),
)
第二种情况(start_url的响应页面下方没有翻页链接,要进入a 标签链接才有翻页链接):
这种情况下,就不能在rules定义翻页规则了,因为即使定义了翻页规则,也找不到,因为rules里面的所有规则,第一次获取响应页面都是对应start_url地址的内容,在这个页面上没有符合Rule规则的,就找不到了,这里我也不多说了,直接去源码吧!
class TestSpider(CrawlSpider):
name = \'test\'
allowed_domains = [\'dangdang.com\']
start_urls = [\'http://book.dangdang.com/\']
rules = (
Rule( Extractor(restrict_xpaths=(\"//div[@class=\'conflq_body\']/div[@name=\'m403752_pid5438_t10274\']//div/dl[@ddt-area=\'5358\']/dd\")), callback=\'parse_item\'),
)
def parse_item(self, response):
item={}
item[\'cate_0\']=\'\'
item[\'cate_1\'] = \'\'
item[\'cate_2\'] = \'\'
item[\'cate_3\'] = \'\'
breadcrum=response.xpath(\"//div[@class=\'crumbs_fb_left\']/div[@class=\'select_ \']/a[@name=\'breadcrumb-category\']/text()\").getall()
for i in range(len(breadcrum)):
item[\'cate_{}\'.format(i)]=breadcrum[i]
book_li=response.xpath(\"//div[@id=\'search_nature_rg\']/ul/li\")
for li in book_li:
item[\'book_ \']=li.xpath(\".//p[@class=\'name\']/a/@ \").get()
item[\'book_price\']=li.xpath(\".//p[@class=\'price\']/span/text()\").get()
item[\'book_url\']=li.xpath(\".//p[@class=\'name\']/a/@href\").get()
book_search=li.xpath(\".//p[@class=\'search_book_author\']/span\")
item[\'book_author\']=book_search[0].xpath(\".//a/@ \").get()
item[\'public_date\']=book_search[1].xpath(\".//text()\").get()
item[\'public_date\']=re.sub(\"/\",\'\',item[\'public_date\']) if item[\'public_date\'] else None
item[\'public_company\']=book_search[2].xpath(\".//a/@ \").get()
yield item
next_page_url=response.xpath(\"//div[@class=\'paging\']//li[@class=\'next\']/a/@href\").get()
next_page=\"http://category.dangdang.com\"+next_page_url
yield scrapy.Request(next_page,callback=self.parse_item)
这种情况下的翻页要在函数里面进行,在parse_item()函数的最后三行,是翻页语句!自己可以测试一下,我也不知道rules规则能不能有其它方法可以做到,反正我现在没发现,如果有朋友知道的可以告诉一下!
以上是我自己的个人观点,如有错漏烦请指出!
继续阅读与本文标签相同的文章
如何正确使用充电宝
网站服务器、网站域名、公司品牌、口号、程序
-
第六届世界互联网大会“新看点”大盘点
2026-05-14栏目: 教程
-
特斯拉自动驾驶系统涨价遭质疑 马斯克:我们不能一直亏钱
2026-05-14栏目: 教程
-
首个二类资源区平价光伏电站正式并网发电
2026-05-14栏目: 教程
-
AI+5G科技创新 视频行业呈现轻应用化趋势
2026-05-14栏目: 教程
-
1.98亿滴滴用户添加了紧急联系人 每天百万个订单行程分享给亲友
2026-05-14栏目: 教程
