本章我们将会根据特定的 tag 来爬取 " http://quotes.toscrape.com/ "
,的内容。
首先,我们先观察这个网站的 url 结构,以 humor 这个 tag 为例,它的 url 是这样的:" http://quotes.toscrape.com/tag/humor/ "
。可见这个网站某个 tag 的 url 是:" http://quotes.toscrape.com/tag/ + tage_name "
下面我们来构建一个带参数 tag 的爬虫,tag 为我们选择要爬取的 tag。
# -*- coding: utf-8 -*-
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
url = 'http://quotes.toscrape.com/tag/{}'.format(self.tag)
yield scrapy.Request(url, self.parse)
# 根据 tag 页面爬取内容并处理翻页
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
}
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, self.parse)
也可以使用 python 的内置函数 getattr()
来实现。
# -*- coding: utf-8 -*-
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
url = 'http://quotes.toscrape.com/'
# 如果 self.tag 存在返回 tag 本身的值,不存在返回 None
tag = getattr(self, 'tag', None)
if tag is not None:
url = url + 'tag/' + tag
# 把构建好的 url 用 parse() 方法处理
yield scrapy.Request(url, self.parse)
# 根据 tag 页面爬取内容并处理翻页
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
}
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, self.parse)
我们还能直接在 __init__
,用超类的方法来定义 start_urls
:
# -*- coding: utf-8 -*-
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def __init__(self, tag=None, *args, **kwargs):
super(QuotesSpider, self).__init__(*args, **kwargs)
self.start_urls = ['http://quotes.toscrape.com/tag/{}'.format(tag)]
# 根据 tag 页面爬取内容并处理翻页
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
}
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, self.parse)
在命令行使用爬虫爬取时,我们用 -a
来传递参数:
scrapy crawl quotes -o quotes-humor.json -a tag=humor
现在,tag 为 humor 的所有信息都被爬取并保存为 json 文件了。