Scrapy跳转整个HTML元素而非链接的问题排查与解决
问题分析与解决
核心错误点
- 链接提取错误:你用
link.get()获取的是整个<a>标签的HTML代码,而非链接地址,导致Scrapy把整个标签拼接到基础URL后,产生无效的404链接。 - 回调函数错误:
parse里调用response.follow时指定了callback=self.parse,会重复调用列表页解析函数,应该指向处理详情页的parse_links。 - 动态渲染处理缺失:目标网站的链接是通过Knockout.js动态绑定的,静态HTML中
a标签没有实际的href属性,需要从data-bind属性里提取目标URL。 - 详情页选择器无效:
parse_links里的CSS选择器为空,且td.[email_address]是错误写法,无法定位邮箱元素。
修正后的代码
import scrapy import re class ContractorSpider(scrapy.Spider): name = "contractor" start_urls = ['https://lslbc.louisiana.gov/contractor-search/search-type-contractor/'] def parse(self, response): # 从a标签的data-bind属性中提取showURL相关内容 links = response.xpath('//*[@id="search-results"]/table/tbody/tr/td/a/@data-bind') for link in links: data_bind_content = link.get() # 用正则匹配出showURL对应的路径值 url_pattern = re.search(r"'(.*?)'", data_bind_content) if url_pattern: contractor_path = url_pattern.group(1) # 拼接完整的详情页URL full_url = f"https://lslbc.louisiana.gov{contractor_path}" yield scrapy.Request(full_url, callback=self.parse_links) def parse_links(self, response): # 根据页面实际结构调整选择器,这里假设邮箱在class为email_address的td中 contractor_name = response.css('h2.company-title::text').get() contractor_email = response.css('td.email_address::text').get() if contractor_name and contractor_email: yield { 'name': contractor_name.strip(), 'email': contractor_email.strip() }
高效优化建议
目标网站的承包商数据是通过AJAX接口动态加载的,直接解析静态HTML容易受前端渲染逻辑影响。更可靠的方式是:
- 打开浏览器开发者工具的Network面板,过滤XHR请求;
- 找到
admin-ajax.php的请求,复制其URL、请求参数和Headers; - 直接编写请求调用该接口,获取JSON格式的完整承包商数据,无需解析页面链接,效率更高且更稳定。
内容的提问来源于stack exchange,提问作者anon_0122
相关产品推荐
相关产品推荐

