前言
如何优雅的获取同一个网站上下一次爬取的链接并放到生成一个 Scrapy Response 呢?
样例
from urllib import parse
import scrapy
class SitoiSpider(scrapy.Spider):
name = "sitoi"
start_urls = [
'https://sitoi.cn',
]
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = parse.urljoin(response.url, href)
yield scrapy.Request(url=url, callback=self.parse_next)
def parse_next(self, response):
print(response.url)
方式一:使用 urllib 库来拼接 URL
这个方式是通过 urllib
库来对下一个 url 进行补全成完整的 url,再使用 scrapy.Request
的方式进行下一个页面的爬取。
优点
- 在处理每一个 href 的时候可以添加一些自定义的内容(例如记录一下当前第几页了等等)
缺点
- 需要引入其他的库
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = parse.urljoin(response.url, href)
yield scrapy.Request(url=url, callback=self.parse_next)
方式二:使用 response 自带的 urljoin
这个方式是通过 Scrapy response 自带的 urljoin
对下一个 url 进行补全成完整的 url,再使用 scrapy.Request
的方式进行下一个页面的爬取。(和方式一基本相同)
优点
- 不再需要在 spider 文件中引入多的第三方库。
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = response.urljoin(href)
yield scrapy.Request(url=url, callback=self.parse_next)
方式三:使用 response 自带的 follow
这个方式是通过 Scrapy response 自带的 follow
进行下一个页面的爬取。
优点
- 不再需要在 spider 文件中引入多的第三方库。
- 不需要写
extract()
来提取 href 字符串,只需要传入 href 这个Selector
(可选) - 不需要写 url 拼接
xpath
只需要编写到a
标签即可,可以省略掉@href
,即不需要获取 href 的Selector
,直接传递 a 的Selector
(可选)
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)
变种一
- 不写
extract()
来提取 href 字符串,传入 href 这个Selector
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href")
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)
变种二
- 不写
extract()
来提取 href 字符串,传入 href 这个Selector
xpath
不写@href
,直接传递 a 的Selector
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/")
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)
方式四:使用 response 自带的 follow_all
这个方式是通过 Scrapy response 自带的 follow_all
进行下一个页面的爬取。
优点
- 不再需要在 spider 文件中引入多的第三方库。
- 不需要写
extract()
来提取 href 字符串,只需要传入 href 这个 selector(可选) - 不需要写 url 拼接
- 只需要编写到
a
标签即可,可以省略掉@href
,即不需要获取 href 的SelectorList
,直接传递 a 的SelectorList
(可选) - 不需要编写遍历,直接把抓到的 url 的
SelectorList
放入即可
缺点
- 如果中间还有什么逻辑,就不太适用了(例如记录一下当前第几页了等等)
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a")
yield from response.follow_all(urls=href_list, callback=self.parse_next)
变种
注:前方高能
一行代码搞定。
def parse(self, response):
yield from response.follow_all(xpath="//div[@class='card']/a", callback=self.parse_next)
欢迎访问我的个人博客:https://sitoi.cn