【问题标题】:JSON KeyError on Wayback Machine scraperWayback Machine 刮刀上的 JSON KeyError
【发布时间】:2015-11-30 02:26:24
【问题描述】:

我正在构建一个简单的程序来从 URL 列表中获取所有页面标题,然后将它们写入 CSV 文件。我已经完成并理解了大多数部分,除了一件事:无论我如何更改代码,我都会一遍又一遍地收到 Key Error。请看一下并告诉我这些代码有什么问题:

import requests
import json
import urllib2
import csv
from BeautifulSoup import BeautifulSoup

def getsnapshot(domain):
    base = 'http://archive.org/wayback/available?url='
    r = requests.get(base+domain, verify=False)
    j = json.loads(r.text)
    if j['archived_snapshots'] == {}:
        pass
    else:
        archive_url = j['archived_snapshots']['closest']['url']
    return archive_url

def gettitle(url):
    soup = BeautifulSoup(urllib2.urlopen(getsnapshot(url)))
    return soup.title.string

def writecsv(domain):
    c = csv.writer(open("output.csv", "wb"))
    snapshoturl = getsnapshot(domain)
    title = gettitle(snapshoturl)
    c.writerow([domain,title])

with open('input.txt', 'r') as f:
    for line in f.read().splitlines():
        writecsv(line)

我的输入只是一个 URL 列表,特别是域名。我正在检查域历史记录,看看过去是否有垃圾邮件。

这是 JSON

{
  "archived_snapshots": {
    "closest": {
      "available": true,
      "url": "http://web.archive.org/web/20050408030822/http://www.001music.net:80/",
      "timestamp": "20050408030822",
      "status": "200"
    }
  }
}

【问题讨论】:

    标签: python json beautifulsoup


    【解决方案1】:

    您是否尝试过使用r.json()?它内置于requests lib
    KeyError 通常与您对 object 或 dict 的操作有关,但您没有向我们展示 json。

    另外,requests 可以替换 urllib2。我会尝试只使用requests

    【讨论】:

    • 您好,感谢您的推荐。我已经更新了包含 json 的问题。你能再看看吗?
    • 您从哪一行得到错误?和错误信息?
    • 实际上来自getsnapshot(domain) 的条件语句似乎没有返回正确的URL。如果我将其更改为 archive_url = j['archived_snapshots']['closest']['url'] if not j['archived_snapshots'] else '' 它会产生 KeyError : 'closest'
    • 所以您在没有这样的密钥时尝试访问closest。查看您的返回值并进行相应调整
    【解决方案2】:

    我认为您的问题是您假设如果j['archive_snapshots'] 不为空,它将始终包含一个键映射“最接近”到包含键“url”的字典。验证这个假设,你应该做得很好:

    if 'archived_snapshots' in j and j['archived_snapshots']:
        return j['archived_snapshots'].get('closest',{}).get('url')
    

    如果这些假设中的任何一个是 False,这将返回 None,因此请相应地调整 getsnapshot() 的调用者以仅在 URL is not None 时继续(或者,引发异常并将调用包装在 @987654327 @块)

    此外,您当前的代码将覆盖您添加的每个新行的文件。以附加模式打开 (open("output.csv", "a")) 或更有效地,将您的 for 循环包装在额外的 with 调用中,并将 csv.writer() 对象直接传递给 writecsv()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-20
      • 1970-01-01
      • 1970-01-01
      • 2012-11-19
      • 2019-08-31
      • 2017-07-18
      • 2021-10-19
      • 2022-01-25
      相关资源
      最近更新 更多