You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy LinkExtractor与ScraperApi集成:链接缺失域名问题解决

解决Scrapy+ScraperAPI时链接域名错误导致404的问题

问题原因

你当前代码直接将ScraperAPI生成的代理URL(https://api.scraperapi.com/?url=...)放入start_urls,Scrapy处理响应时会把这个代理URL作为基础域名。当LinkExtractor提取到/rated...这类相对路径时,会自动拼接到代理域名后,形成https://api.scraperapi.com/rated...,自然返回404。

解决方案

方案一:使用ScraperAPI官方Downloader Middleware(推荐)

通过中间件统一处理代理,让Scrapy始终以目标站点URL作为基础域名,自动正确拼接相对链接。

  1. 修改爬虫代码:恢复原始目标站点的start_urls和allowed_domains,去掉直接调用client.scrapyGet的逻辑:
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class Sip2Spider(CrawlSpider):
    name = 'sip2'
    allowed_domains = ['homeadvisor.com']
    start_urls = ['https://www.homeadvisor.com/c.Additions-Remodeling.Atlanta.GA.-12001.html']

    rules= [
        Rule(LinkExtractor(allow="/rated"), callback="parse_page", follow=True)
    ]

    def parse_page(self, response):
        # 修正原CSS选择器的错误(去掉多余的@符号)
        company_name = response.css("h1.w-full.text-3xl::text").get().strip()
        yield {
            "company_name" : company_name
        }
  1. 配置Scrapy Settings:在settings.py中添加ScraperAPI中间件配置:
# 启用ScraperAPI下载中间件
DOWNLOADER_MIDDLEWARES = {
    'scraper_api.ScraperAPIMiddleware': 543,
}
# 填入你的ScraperAPI密钥
SCRAPER_API_KEY = '67e5e7755771b9abf8062e595dd5cc2a'

方案二:手动修正提取的链接

如果不想使用中间件,可以通过LinkExtractor的process_value参数,手动给相对链接拼接目标站点域名:

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scraper_api import ScraperAPIClient
from urllib.parse import urljoin

client = ScraperAPIClient("67e5e7755771b9abf8062e595dd5cc2a")

def fix_link(url):
    # 给相对链接拼接目标站点域名
    return urljoin('https://www.homeadvisor.com', url)

class Sip2Spider(CrawlSpider):
    name = 'sip2'
    start_urls =[client.scrapyGet(url = 'https://www.homeadvisor.com/c.Additions-Remodeling.Atlanta.GA.-12001.html')]

    rules= [
        # 使用process_value修正链接
        Rule(LinkExtractor(allow="/rated", process_value=fix_link), callback="parse_page", follow=True)
    ]

    def parse_page(self, response):
        company_name = response.css("h1.w-full.text-3xl::text").get().strip()
        yield {
            "company_name" : company_name
        }

注意:此方案需要确保后续请求也通过ScraperAPI代理,建议配合中间件使用,否则需要在回调中手动用client.scrapyGet包装每个新请求。

额外修正点

原代码中的CSS选择器h1.@w-full.@text-3xl存在语法错误,需去掉类名前的@符号,改为h1.w-full.text-3xl::text才能正确提取内容。

内容的提问来源于stack exchange,提问作者skyriver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:15:37