使用Scrapy爬取SEC苹果公司10K表单指定表格失败求助
问题分析与解决方案
你的问题主要来自三个方面:浏览器渲染DOM与Scrapy获取的原始HTML差异、脆弱的表格索引定位,以及SEC的反爬策略。以下是具体原因和修复方案:
1. DOM结构差异导致XPath失效
Chrome会自动为表格补全<tbody>标签,但SEC返回的原始HTML里并没有这个标签。你在Chrome里用(//table)[13]/tbody能找到元素,是因为浏览器帮你补全了结构,但Scrapy直接获取的原始HTML中,表格是直接以<table><tr>...</tr></table>的形式存在的,所以你的XPath里的/tbody会导致匹配失败。
2. 硬编码表格索引的定位不可靠
用(//table)[13]这种固定索引的方式非常脆弱——只要页面结构有微小变化(比如新增/删除其他表格),这个定位就会直接失效。应该根据表格的上下文或标题做精准定位。
3. SEC的反爬拦截
SEC会限制无标识的爬虫请求,如果你不设置合理的请求头,可能会返回不完整的内容或被直接拦截。
修改后的代码
import scrapy class AaplSpider(scrapy.Spider): name = "aapl" allowed_domains = ["www.sec.gov"] start_urls = ["https://www.sec.gov/ix?doc=/Archives/edgar/data/320193/000032019322000108/aapl-20220924.htm"] # 模拟浏览器请求头,避免被反爬拦截 custom_settings = { 'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } def parse(self, response): # 基于表格标题精准定位,彻底摆脱索引依赖 target_table = response.xpath('//h3[contains(text(), "Purchases of Equity Securities by the Issuer and Affiliated Purchasers")]/following-sibling::table[1]') if not target_table: self.logger.warning("目标表格未找到,请检查页面结构或XPath") return # 遍历表格行,注意原始HTML没有tbody,直接取tr for row in target_table.xpath('.//tr'): # 使用get()替代extract_first()(Scrapy 2.0+推荐写法) yield { 'Periods': row.xpath('.//td[1]//text()').get(), 'Total Number of Shares Purchased': row.xpath('.//td[3]//text()').get(), 'Average Price Paid Per Share': row.xpath('.//td[7]//text()').get() }
关键改动说明
- 添加请求头:通过
custom_settings设置USER_AGENT,模拟正常浏览器请求,避免被SEC拦截 - 精准定位表格:利用目标表格的标题
<h3>标签定位,不再依赖不可靠的表格索引 - 移除tbody:适配原始HTML结构,避免因浏览器自动补全标签导致的XPath匹配失败
- 调试友好:添加日志警告,方便快速排查表格未找到的情况
调试小技巧
如果还是有问题,可以在parse方法里先打印response.text,查看原始HTML的实际结构,确认目标表格的位置和标签情况,这样能更直观地调整XPath。
内容的提问来源于stack exchange,提问作者Matthew
相关产品推荐
相关产品推荐

