You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Scrapy爬取Wanikani汉字数据时txt文件为空问题排查

故障原因

你的爬虫拿不到数据是几个代码错误叠加导致的:

  • XPath路径完全写错:你从浏览器复制的绝对路径带了错误的/body/层级,Scrapy的响应DOM中body节点是html标签的直接子节点,不存在于id="main"的节点内部,所有XPath查询返回空列表,自然没有可写入的数据。同时你在遍历reading节点的循环里又写了全文档绝对路径,就算路径正确也会重复抓取全页数据。
  • 文件操作逻辑错误:你写的self.file.close只是引用了关闭方法,没有加括号执行,而且每写一条数据就尝试关闭文件,后续写入会直接失败;另外在类属性定义阶段就打开文件句柄,不符合Scrapy的生命周期,缓冲区的数据不会自动刷入磁盘,就算写入成功也会丢数据。
  • 反爬拦截:Scrapy默认请求头的User-Agent带Scrapy标识,WaniKani会直接拦截这类请求,返回的页面根本没有你要找的汉字内容;默认开启的robots协议遵守规则也会直接拦截这类爬取请求。
  • 无效代码:你写的x.strip()没有接收返回值,Python字符串是不可变类型,不赋值的话strip操作完全不生效,空白字符不会被清理。
修复步骤
  1. 先修改Scrapy项目的settings.py配置:
    • 把ROBOTSTXT_OBEY = True改成ROBOTSTXT_OBEY = False
    • 替换默认USER_AGENT为普通浏览器标识,比如:
      USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
      
  2. 替换原爬虫代码为修正后的版本,主要修正了XPath定位、文件生命周期管理、数据清洗逻辑:
import scrapy

class WanikaniSpider(scrapy.Spider):
    name = 'japandict'
    allowed_domains = ['www.wanikani.com']         
    base_url = 'https://www.wanikani.com/kanji/'
    kanjis = ['悪' ,'安' ,'以' ,'飲' ,'意' ,'医' ,'員' ,'運' ,'映' ,'英' ,'屋' ,'駅' ,'歌' ,'牛']
    start_urls = [base_url + kanji for kanji in kanjis]

    def open_spider(self, spider):
        # 爬虫启动时统一打开四个文件
        self.kanji_f = open("kanji.txt", "a", encoding="utf-8")
        self.onyomi_f = open("onyomi.txt", "a", encoding="utf-8")
        self.kunyomi_f = open("kunyomi.txt", "a", encoding="utf-8") 
        self.meanings_f = open("meanings.txt", "a", encoding="utf-8")

    def close_spider(self, spider):
        # 爬虫结束时统一关闭文件,强制刷入缓冲区数据
        self.kanji_f.close()
        self.onyomi_f.close()
        self.kunyomi_f.close()
        self.meanings_f.close()

    def parse(self, response):
        # 用class属性定位元素,避免写死层级导致路径失效
        kanji_char = response.xpath('//h1[contains(@class, "kanji-icon")]/span[@lang="ja"]/text()').get('').strip()
        raw_meanings = response.xpath('//h1[contains(@class, "kanji-icon")]/text()').getall()
        meaning = ''.join([m.strip() for m in raw_meanings if m.strip()])

        raw_onyomi = response.xpath('//div[contains(@class, "reading-section--onyomi")]//p/text()').getall()
        onyomi_list = [r.strip() for r in raw_onyomi if r.strip()]
        raw_kunyomi = response.xpath('//div[contains(@class, "reading-section--kunyomi")]//p/text()').getall()
        kunyomi_list = [r.strip() for r in raw_kunyomi if r.strip()]

        # 写入数据,中途不关闭文件
        if kanji_char:
            self.kanji_f.write(kanji_char + "\n")
        for onyomi in onyomi_list:
            self.onyomi_f.write(onyomi + "\n")
        for kunyomi in kunyomi_list:
            self.kunyomi_f.write(kunyomi + "\n")
        if meaning:
            self.meanings_f.write(meaning + "\n")
额外说明

不要直接复制浏览器调试工具生成的一长串绝对XPath路径,这类路径靠div序号定位,页面结构稍微变动就会失效,尽量用元素的id、class等稳定属性做定位,鲁棒性更强。

内容的提问来源于stack exchange,提问作者Lawlace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:18:19