Scrapy爬取bikebd站点返回None且出现乱码,寻求技术帮助
问题分析与解决方案
核心问题
- 请求头未生效:
start_requests方法生成scrapy.Request时未传入headers=self.headers,自定义请求头完全没被使用,服务器返回的响应不符合预期。 - Brotli压缩解码失败:即使请求头生效,其中
accept-encoding包含br(Brotli压缩),而Scrapy默认不支持该格式解码,返回的是未解压的二进制数据,导致页面乱码、XPath无法解析有效HTML,最终返回None。 - 转义引号语法错误:代码中的
"是HTML转义字符,实际运行会触发语法错误,需替换为英文双引号。
分步解决
1. 修复请求头传递问题
修改start_requests方法,确保请求携带自定义headers:
def start_requests(self): urls = ["https://www.bikebd.com/brand/yamaha"] for url in urls: # 新增headers参数,使自定义请求头生效 yield scrapy.Request(url=url, callback=self.parse, headers=self.headers)
2. 解决Brotli压缩解码问题(二选一)
方案一:移除br编码(简单直接)
修改headers中的accept-encoding,仅保留Scrapy原生支持的压缩格式:
headers = { 'accept': '*/*', # 移除br编码,只保留gzip和deflate 'accept-encoding': 'gzip, deflate', 'accept-language': 'en-US,en;q=0.9,da;q=0.8', 'cache-control':'no-cache', # 替换所有"e;为英文双引号 'cookie': '_ga=GA1.1.1549289426.1669609851; XSRF-TOKEN=eyJpdiI6IjhCN1BnV0RoK3dOQnFEQlhYRUZVZEE9PSIsInZhbHVlIjoiTFQ4Ym15MWhoU1hmR3FxaWdVYnkvbnovMTVDbS9iRm1OVCsrV0F2RzA5dHlmMWpObENoSFBWY0VXclBNWkZaNlV1aitwSXBWNjhNMGs2Z3JqQ3ZvQWVIQ25QcnNOZkNpR3lwMGNkL01aWHM3VDZ5YmZJblRha0kyUk5IMTh2UzQiLCJtYWMiOiJjMzFmMDZlZDFjNzVhNTVlZjY1MWEzNWJkZjY5Y2Q1MjFiZmNmM2UxOWRiZWJlMGRhZWY5OGU0MGQ4OWI5N2ViIiwidGFnIjoiIn0%3D; bikebd_session=eyJpdiI6ImVVb2NqcmFLR2dKSXc2NnNqUlV6ZWc9PSIsInZhbHVlIjoibUVNcEZidUxsbWdkK3c2UDFYdDYwcHFOdVU1WmVXY0ZiV1pHRzJBbzlaUDNuWGl2Vk1OTk5QYnRkdmVXdDg3bEx2SEpiMGE1c2dvakdkU0tQOTBucHc5ajRpcGpod2ViL3B2ME9DRXc4SUFtSG56YU9MVTdEVi9rYW8reXk0TDYiLCJtYWMiOiI5MmU2NWEyZDhkOGFiNTdkYzQ0ZGJhMDQwNzFhYzFmOGY4MzNjNWU2ODczYWNiOTVlNjU4MWUyZWVmMzE5NjNmIiwidGFnIjoiIn0%3D; _ga_HEG073JLWK=GS1.1.1670663205.2.1.1670663540.0.0.0', 'pragma': 'no-cache', 'referer': 'https://www.bikebd.com/bike-price-in-bd', 'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': "Windows", 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', }
方案二:安装Brotli支持(保留br编码)
若需继续使用br压缩编码,安装Scrapy的Brotli扩展:
pip install scrapy[Brotli]
安装后Scrapy会自动处理Brotli压缩的响应,无需修改请求头。
3. 修正XPath(确保内容提取有效)
解决编码问题后,用open_in_browser(response)打开页面确认HTML结构,调整XPath。例如页面车型标题实际位于h3.ltn__product-title a中,修改后的parse方法:
def parse(self, response): # 打开页面调试(可选) open_in_browser(response) # 替换为实际有效的容器XPath container = response.xpath("//div[contains(@class, 'ltn__product-item')]") for item in container: title = item.xpath(".//h3[@class='ltn__product-title']/a/text()").get() if title: yield {'title': title.strip()}
内容的提问来源于stack exchange,提问作者Bashar
相关产品推荐
相关产品推荐

