【问题标题】:Extract from dynamic JSON response with Scrapy使用 Scrapy 从动态 JSON 响应中提取
【发布时间】:2016-11-13 15:20:36
【问题描述】:

我想从如下所示的 JSON 输出中提取“可用”值。

{
    "result": {
        "code": 100,
        "message": "Command Successful"
    },
    "domains": {
        "yolotaxpayers.com": {
            "avail": false,
            "tld": "com",
            "price": "49.95",
            "premium": false,
            "backorder": true
        }
    }
}

问题是['avail']的值在["domains"]["domain_name"]之下,我不知道如何获取域名。

下面有我的蜘蛛。第一部分工作正常,但不是第二部分。

import scrapy
import json
from whois.items import WhoisItem

class whoislistSpider(scrapy.Spider):
    name = "whois_list"
    start_urls = []
    f = open('test.txt', 'r')
    global lines
    lines = f.read().splitlines()
    f.close()
    def __init__(self):
        for line in lines:
            self.start_urls.append('http://www.example.com/api/domain/check/%s/com' % line)

    def parse(self, response):
        for line in lines:
            jsonresponse = json.loads(response.body_as_unicode())
            item = WhoisItem()
            domain_name = list(jsonresponse['domains'].keys())[0]
            item["avail"] = jsonresponse["domains"][domain_name]["avail"]
            item["domain"] = domain_name
            yield item

提前感谢您的回复。

【问题讨论】:

    标签: python json web-scraping scrapy web-crawler


    【解决方案1】:

    目前,它尝试通过"('%s.com' % line)" 键获取值。

    您需要正确地进行字符串格式化:

    domain_name = "%s.com" % line.strip()
    item["avail"] = jsonresponse["domains"][domain_name]["avail"]
    

    【讨论】:

    • 谢谢@alecxe。它有效,但现在我收到item["avail"] = jsonresponse["domains"][domain_name]["avail"] KeyError: 'qqqqq.com' 我认为它与引号相关,对吧?
    【解决方案2】:

    假设您只期望每个响应有一个结果:

    domain_name = list(jsonresponse['domains'].keys())[0]
    item["avail"] = jsonresponse["domains"][domain_name]["avail"]
    

    即使文件“test.txt”中的域与结果中的域不匹配,这也会起作用。

    【讨论】:

    • 谢谢@Dean 它工作正常,但它进入了一种循环。对于 17 个检查域,我得到了 289 个结果,其中有很多重复项。你知道如何摆脱这个循环吗?
    • @CristianCalin 似乎在您的 parse 函数中,您正在添加到域列表(以及在 init 中),这可能是无限循环的来源。
    • 我将class 中的域列表向上移动,并将lines 定义为全局,但仍然是相同的循环。
    • 请使用更新后的代码编辑您的问题。这可能与 scrapy 检查重复 url 的方式有关。
    • 为什么要将所有域都添加到“allowed_domains”中,您的意思是要将爬虫发送给他们吗?也许它认为 WhoisItem 是下一个爬行阶段...
    【解决方案3】:

    要从上面的 json 响应中获取域名,您可以使用 list comprehension ,例如:

    domain_name = [x for x in jsonresponse.values()[0].keys()]

    要获取“可用”值,请使用相同的方法,例如:

    avail = [x["avail"] for x in jsonresponse.values()[0].values() if "avail" in x]

    要获取字符串格式的值,您应该通过索引 0 调用它,例如:

    domain_name[0]avail[0] 因为列表解析结果存储在列表类型变量中。

    More info on list comprehension

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 2013-08-12
      • 1970-01-01
      • 2021-11-29
      • 2013-08-23
      相关资源
      最近更新 更多