添加Bright Data代理后Scrapy抓取USPTO专利页面选择器失效如何解决
适配代理返回内容的调整方案
1. 替换硬编码绝对路径Xpath
原有基于元素层级和序号的绝对路径Xpath(//html/body/table[2]/tr/td[2]/b)鲁棒性极低,只要代理返回的页面调整了任意元素位置就会失效,改为基于字段语义的相对匹配规则,同时兼容大小写差异:
# Xpath中内置大小写转换+空白符归一化逻辑,适配两种返回结果的差异 normalize_rule = "normalize-space(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))" # 匹配专利号:找包含专利号标识的节点后的<b>标签内容 patent_num_xpath = f"//*[contains({normalize_rule}, 'patent number')]/following-sibling::b//text()" patent['number'] = response.xpath(patent_num_xpath).get('').replace(',', '').strip() # 匹配专利日期:找包含专利日期标识的节点后的<b>标签内容 patent_date_xpath = f"//*[contains({normalize_rule}, 'date of patent')]/following-sibling::b//text()" patent['date'] = cleaned(response.xpath(patent_date_xpath).get('').strip())
2. 统一预处理响应文本消弭差异
在解析页面前先对响应内容做归一化处理,直接消除换行、大小写带来的影响:
import re from scrapy.selector import Selector # 统一替换所有连续空白(包含换行、制表符)为单个空格,再统一转为全大写 processed_text = re.sub(r'\s+', ' ', response.body.decode('utf-8', errors='ignore')).upper() # 用处理后的文本构造选择器,后续直接用该选择器查询 sel = Selector(text=processed_text) # 此时可以直接用全大写的规则匹配,不需要额外处理大小写 patent['number'] = sel.xpath('//*[contains(text(), "PATENT NUMBER")]/following-sibling::b//text()').get('').replace(',', '').strip()
3. 优化取值逻辑避免报错
原有getall()[0]的写法在匹配结果为空时会直接抛出索引越界异常,改为get(default='')的安全取值方式,匹配失败时返回空字符串,不会直接中断爬虫运行,可后续补充异常兜底逻辑。
内容的提问来源于stack exchange,提问作者abubutanu
相关产品推荐
相关产品推荐

