แยกจากการตอบสนอง JSON แบบไดนามิกด้วย Scrapy

ฉันต้องการแยกค่า 'avail' ออกจากเอาต์พุต 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

ขอขอบคุณล่วงหน้าสำหรับการตอบกลับของคุณ


person Cristian Calin    schedule 11.07.2016    source แหล่งที่มา


คำตอบ (3)


สมมติว่าคุณคาดหวังเพียงผลลัพธ์เดียวต่อการตอบกลับ:

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

วิธีนี้จะได้ผลแม้ว่าจะมีความไม่ตรงกันระหว่างโดเมนในไฟล์ "test.txt" และโดเมนในผลลัพธ์ก็ตาม

person Dean Fenster    schedule 11.07.2016
comment
ขอบคุณ @Dean มันใช้งานได้ดี แต่มันกลับกลายเป็นวนซ้ำ สำหรับโดเมนที่ตรวจสอบ 17 โดเมน ฉันได้รับผลลัพธ์ 289 รายการและมีรายการซ้ำกันมากมาย คุณมีความคิดบ้างไหมว่าจะหลบหนีจากวงจรนี้ได้อย่างไร? - person Cristian Calin; 11.07.2016
comment
@CristianCalin ดูเหมือนว่าในฟังก์ชัน parse ของคุณคุณกำลังเพิ่มลงในรายการโดเมน (และใน init ด้วย) นี่อาจเป็นแหล่งที่มาของการวนซ้ำไม่สิ้นสุด - person Dean Fenster; 11.07.2016
comment
ฉันย้ายรายการโดเมนขึ้นไปใน class และกำหนด lines ให้เป็นระดับโลก แต่ยังคงเป็นวงเดียวกัน - person Cristian Calin; 11.07.2016
comment
โปรดแก้ไขคำถามของคุณด้วยรหัสที่อัปเดต นี่อาจมีบางอย่างเกี่ยวข้องกับวิธีการตรวจสอบ URL ที่ซ้ำกัน - person Dean Fenster; 11.07.2016
comment
เหตุใดคุณจึงเพิ่มโดเมนทั้งหมดลงใน Allow_domains คุณตั้งใจจะส่งโปรแกรมรวบรวมข้อมูลไปให้โดเมนเหล่านั้นหรือไม่ บางทีอาจถือว่า WhoisItem เป็นขั้นตอนต่อไปของการรวบรวมข้อมูล... - person Dean Fenster; 11.07.2016
comment
ฉันได้ลบบรรทัดเหล่านั้นและอัปเดตโค้ดแล้ว แต่น่าเสียดายที่ฉันได้ผลลัพธ์เดียวกัน @คณบดีเฟนสเตอร์ - person Cristian Calin; 11.07.2016
comment
@CristianCalin คุณสามารถเพิ่มรหัสสำหรับ WhoisItem ที่คุณใช้อยู่ได้ไหม? ไม่ว่าจะที่นี่หรือในคำถามติดตามผล (เนื่องจากเราออกนอกหัวข้อ) - person Dean Fenster; 11.07.2016
comment
ขอบคุณ @DeanFenster ฉันได้โพสต์คำถามใหม่ที่นี่ stackoverflow.com/questions/38315087/ - person Cristian Calin; 11.07.2016

ขณะนี้พยายามรับค่าด้วยปุ่ม "('%s.com' % line)"

คุณต้องจัดรูปแบบสตริงให้ถูกต้อง:

domain_name = "%s.com" % line.strip()
item["avail"] = jsonresponse["domains"][domain_name]["avail"]
person alecxe    schedule 11.07.2016
comment
ขอบคุณ @alecxe มันใช้งานได้ แต่ตอนนี้ฉันได้รับ item["avail"] = jsonresponse["domains"][domain_name]["avail"] KeyError: 'qqqqq.com' ฉันคิดว่ามันเกี่ยวข้องกับคำพูดใช่ไหม - person Cristian Calin; 11.07.2016

หากต้องการรับชื่อโดเมนจากการตอบกลับ json ด้านบน คุณสามารถใช้ list comprehension เช่น:

domain_name = [x สำหรับ x ใน jsonresponse.values()[0].keys()]

หากต้องการรับค่า "avail" ให้ใช้วิธีการเดียวกัน เช่น:

avail = [x["avail"] สำหรับ x ใน jsonresponse.values()[0].values() ถ้า "avail" ใน x]

หากต้องการรับค่าในรูปแบบสตริงคุณควรเรียกมันด้วยดัชนี 0 เช่น:

domain_name[0] และ avail[0] เนื่องจากผลลัพธ์ของความเข้าใจรายการถูกจัดเก็บไว้ในตัวแปรประเภทรายการ

ข้อมูลเพิ่มเติมเกี่ยวกับความเข้าใจในรายการ

person vikas0713    schedule 11.07.2016