前言
如何優雅的獲取同一個網站上下一次爬取的鏈接並放到生成一個 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