Scrapy爬取文章返回空结果,XPath表达式报错如何解决?
问题解决方案
1. 修复触发报错的XPath语法错误
你的parse方法里的XPath存在语法错误://*[@class="stories-list"]//*[@class=["story clearfix "]/a/@href,其中[@class=["story clearfix "]的写法不符合XPath规范,直接导致了XPathEvalError。
修正后的XPath(精确匹配文章列表项):
//div[@class="stories-list"]//div[@class="story clearfix"]/a/@href
2. 适配页面结构修正详情页XPath
针对目标网站的实际DOM结构,调整详情页的XPath以确保能正确提取信息:
- 发布日期:优先提取meta标签中的标准格式日期,比直接取文本更可靠
//meta[@property="article:published_time"]/@content - 文章标题:精确匹配标题标签的class属性
//h1[@class="article-title"]/text() - 文章正文:简化class匹配,避免依赖Angular动态生成的类名
//div[@class="article-content"]//p/text()
3. 完整修正后的代码
import scrapy from scrapy import Request from scrapy.crawler import CrawlerProcess class BarchartSpider(scrapy.Spider): name = 'barchart' start_urls = ['https://www.barchart.com/news/commodities/energy'] custom_settings = { 'CONCURRENT_REQUESTS_PER_DOMAIN': 1, 'DOWNLOAD_DELAY': 1, 'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36' } def start_requests(self): for url in self.start_urls: yield Request(url, callback=self.parse) def parse(self, response): # 遍历所有文章链接 for link in response.xpath('//div[@class="stories-list"]//div[@class="story clearfix"]/a/@href'): full_url = response.urljoin(link.get()) yield Request(full_url, callback=self.parse_item) def parse_item(self, response): yield { 'date': response.xpath('//meta[@property="article:published_time"]/@content').get(), 'title': response.xpath('//h1[@class="article-title"]/text()').get().strip(), 'text': ' '.join([p.strip() for p in response.xpath('//div[@class="article-content"]//p/text()').getall() if p.strip()]) } if __name__ == '__main__': process = CrawlerProcess() process.crawl(BarchartSpider) process.start()
额外提示
- 网站可能存在反爬机制,保持
DOWNLOAD_DELAY并使用真实浏览器的USER_AGENT能降低被拦截的概率 - 如果文章列表是滚动加载的动态内容,需要结合
scrapy-splash或Playwright处理JavaScript渲染的页面 - 定期验证XPath有效性,网站DOM结构可能会随版本更新变化
内容的提问来源于stack exchange,提问作者nomnomyang
相关产品推荐
相关产品推荐

