让我们讨论一下,你希望获得整个网站的语录而不是仅仅的爬取开始http://quotes.toscrape.com,给的两个网页。
现在你理解了如何从网页中提取数据,让我们了解如何从开始的链接来追踪后续链接。
首先是从网页中提取我们想要追踪的链接。检查测试我们的网页,我们可以看到下一页的链接,以HTML标记:
<ul class = "pager">
<li class = "next">
<a href = "/page/2/">Next <span aria-hidden = "true">→</span></a>
</li>
</ul>
我们可以尝试在shell中提取它:
>>>response.css('li.next a').extract_first()
'<a href = "/page/2/">Next <span aria-hidden = "true">→</span></a>'
我们提取了标签元素,但是我们想要其中属性的href值。为此,Scarpy提供CSS的扩展应用让我们提取属性中的内容,像这样:
>>>response.css('li.next a::attr(href)').extract_first()
'/page/2/'
现在修改我们的爬虫来递归下一页的功能,从网页中提取数据:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield{
'text':quote.css('span.text::text').extract_first(),
'author':quote.css('span.text:text').extract_first(),
'tags':quote.css('div.tags a.tag::text').extract(),
}
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback = self.parse)
现在提取数据后,parse()方法查找下一页的链接,以urljoin()方法建立网站完整的URL,向下一页生成新请求,为下一页的链接提取数据注册它本身为返回函数同时保持爬取整个网站。
你看到的是Scrapy追踪链接的机制:当你在返回函数中生成请求,Scrapy将会安排请求被发送和注册返回函数被执行,直到请求结束。
使用这方法,你可以搭建复杂的爬虫来追踪你需要的深度,同时在你访问的网页中提取数据。
在我们的例子中,它创建了一个循环,追踪所有网页的链接——让我们来爬取具有标记页数的博客、论坛和其他网站。