LinkExtractor类
- 基本概念
在爬取一个网站时,想要爬取的数据通常分布在多个页面中,每个页面包含一部分数据以及到其他页面的链接,提取链接有使用Selector
和使用LinkExtractor
两种方法。Selector
常用的有CSS Selector
和Xpath
,在Scrapy
框架中,内置了LinkExtractor
类来爬取页面中的链接。
LinkExtractor
类的对象作用是从网页(即Response
对象)中抽取最终将会被follow
链接。LinkExtractor
有唯一的公共方法是 extract_links
,它接收一个Response
对象,并返回一个 scrapy.link.Link
对象。Link Extractor
要实例化一次并且 extract_links
方法会根据不同的response
调用多次提取链接。
- 例子
进入实验环境:
scrapy shell http://hz.ganji.com/zufang/pn2/
导入 LinkExtractor
库:
from scrapy.linkextractors import LinkExtractor
创建 LinkExtractor
对象,设置正则规则,从当前页面中寻找目标链接:
le = LinkExtractor(r'http://hz.ganji.com/zufang/\d+x.shtml')
le.extract_links(response)
查看获取的Link
对象:
print([link for link in le.extract_links(response)])
CrawlSpider
实例
根据CrawlSpider
运行机制,在理解类LinkExtractor
类的使用方法后,接下来实操一下如何用CrawlSpider
爬虫获取数据。
接着上面的例子,我们获取详情页的标题和价格信息,代码如下:
class Ganji2Spider(CrawlSpider):
name = 'ganji2'
allowed_domains = ['ganji.com']
start_urls = ['http://hz.ganji.com/zufang/pn1/']
get_links = []
# 匹配规则,匹配正则然后给回调函数
rules = (
Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/\d+x.shtml'), callback='parse_item', follow=False),
)
def parse_item(self, response):
item = {}
item['title'] = response.xpath('//p[@class="card-title"]/i/text()').get()
item['price'] = response.xpath('//span[@class="price"]/text()').get()
print(item)
follow
机制
现在已经可以从start_urls
开始获取页面中包含的详情页链接,并获取其中的标题和价格信息。那么,如何不断的获取新的页面,再爬起详情页中的数据呢?
在basic spider
中,我们通过parse函数中使用xpath
定位下一页元素,然后将获取的链接重新请求parse函数,从而对下一页发起请求并获得响应。【爬虫】-011-Scrapy-获取下级页面的链接
在CrawlSpider
中,对链接对提取使用LinkExtractor
类,所以从start_urls
请求后得到的response
中分析下一页链接的特点,用正则表达式匹配出来。
得到的下一页链接通过请求,继续得到响应response
,然后对这个response
,分析其中的详情页链接,请求详情页获得响应,并使用parse_item
获取响应中的数据。更详细的原理介绍可以看这里
好了,如此可以更新我们的CrawlSpider
爬虫。
class Ganji2Spider(CrawlSpider):
name = 'ganji2'
allowed_domains = ['ganji.com']
start_urls = ['http://hz.ganji.com/zufang/pn1/']
# 获取的链接列表
get_links = []
# 匹配规则,匹配正则然后给回调函数
rules = (
Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/\d+x.shtml'), callback='parse_item', follow=False),
# 下一页链接的正则规则,持续跟进,不断发起请求
Rule(LinkExtractor(allow=r'http://hz.ganji.com/zufang/pn\d/')),
)
def parse_item(self, response):
item = {}
# 请求下一页得到的响应中的详情页链接,将返回的响应装入列表
self.get_links.append(response)
# 查看响应的链接地址,通过计算列表长度来计数
print(response.url, len(self.get_links))
print('*' * 10)
item['title'] = response.xpath('//p[@class="card-title"]/i/text()').get()
item['price'] = response.xpath('//span[@class="price"]/text()').get()
print(item)
网友评论