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作为基础域名,自动正确拼接相对链接。
- 修改爬虫代码:恢复原始目标站点的
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 }
- 配置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
相关产品推荐
相关产品推荐

