使用Scrapy和Selenium爬取Justdial遇403、504错误怎么解决?
解决方案
Justdial的反爬机制包含请求头校验、TLS指纹识别、IP行为风控、自动化特征检测多层拦截,常规Scrapy请求特征过于明显会被直接拦截,可按以下步骤调整:
1. 调整Scrapy基础配置
首先修改settings.py避免爬虫遇到异常状态码直接退出,同时匹配浏览器请求特征:
- 允许接收403、504响应用于后续重试:
HTTPERROR_ALLOWED_CODES = [403, 504] RETRY_TIMES = 5
- 补充完整的浏览器标准请求头,不要仅传入User-Agent,同时保证请求头顺序和Chrome浏览器一致:
DEFAULT_REQUEST_HEADERS = { 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'sec-ch-ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'none', 'sec-fetch-user': '?1', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' }
- 降低请求频率避免触发限流:
DOWNLOAD_DELAY = 3 RANDOMIZE_DOWNLOAD_DELAY = True CONCURRENT_REQUESTS = 1
2. 解决TLS指纹与自动化特征检测问题
Scrapy默认的TLS握手特征和浏览器差异极大,普通Selenium也存在明显的自动化标记,很容易被识别,可替换为undetected-chromedriver发起请求,示例代码如下:
import undetected_chromedriver as uc import scrapy class JustSpider(scrapy.Spider): name = 'school' start_urls = [ 'https://www.justdial.com/Delhi/search?q=Schools' ] def start_requests(self): # 调试阶段可关闭headless模式,稳定运行后再开启 driver = uc.Chrome(headless=True, use_subprocess=True) for url in self.start_urls: driver.get(url) # 等待页面动态内容加载完成 driver.implicitly_wait(10) page_source = driver.page_source yield scrapy.Request( url=url, callback=self.parse, body=page_source, encoding='utf-8' ) driver.quit() def parse(self, response): title = response.css('title::text').extract() yield {'titletext': title}
3. 代理层优化
普通VPN、数据中心代理被Justdial拦截的概率极高,建议使用高匿住宅代理池,每个请求随机切换IP,避免同一IP短时间内多次请求触发风控。
备选方案
如果网页端爬取成本过高,可以尝试抓包Justdial移动端APP的搜索接口,移动端接口反爬规则更简单,拿到接口签名规则后直接请求接口获取结构化数据,效率远高于网页爬取。
内容的提问来源于stack exchange,提问作者Rishabh Chauhan
相关产品推荐
相关产品推荐

