Scrapy 小技巧(一):使用 scrapy 自帶的函數(follow & follow_all)優雅的生成下一個請求


前言

如何優雅的獲取同一個網站上下一次爬取的鏈接並放到生成一個 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 的方式進行下一個頁面的爬取。

優點

  1. 在處理每一個 href 的時候可以添加一些自定義的內容(例如記錄一下當前第幾頁了等等)

缺點

  1. 需要引入其他的庫
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 的方式進行下一個頁面的爬取。(和方式一基本相同)

優點

  1. 不再需要在 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 進行下一個頁面的爬取。

優點

  1. 不再需要在 spider 文件中引入多的第三方庫。
  2. 不需要寫 extract() 來提取 href 字符串,只需要傳入 href 這個 Selector(可選)
  3. 不需要寫 url 拼接
  4. 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)

變種一

  1. 不寫 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)

變種二

  1. 不寫 extract() 來提取 href 字符串,傳入 href 這個 Selector
  2. 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 進行下一個頁面的爬取。

優點

  1. 不再需要在 spider 文件中引入多的第三方庫。
  2. 不需要寫 extract() 來提取 href 字符串,只需要傳入 href 這個 selector(可選)
  3. 不需要寫 url 拼接
  4. 只需要編寫到 a 標簽即可,可以省略掉 @href,即不需要獲取 href 的 SelectorList,直接傳遞 a 的 SelectorList(可選)
  5. 不需要編寫遍歷,直接把抓到的 url 的 SelectorList 放入即可

缺點

  1. 如果中間還有什么邏輯,就不太適用了(例如記錄一下當前第幾頁了等等)
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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM