簡體   English   中英

如何在scrapy中解析JSON數據

[英]How to parse JSON data in scrapy

我已經在Scrapy中編寫了一個網絡爬蟲,該網絡最初會轉到網頁,抓取每個票據的票據信息,並爬網到“票據”按鈕重定向到的每個鏈接。 在門票頁面上,為了獲得價格,必須請求一個JSON 文件 (現在已經不成問題了),並且需要提取文件中的第一個價格並將其保存到Scrapy商品加載器中。

我試圖使用以下語句在scrapy shell中找到價格對象:

    jsonresponse = json.loads(response.body_as_unicode())
    jsonresponse["p"]

    jsonresponse["lp"]

    jsonresponse['hp']

但由於某種原因,它們都沒有在文件中找到價格對象。 如果您查看門票頁面 ,您可以看到當前最低價格為28美元。 對於此特定鏈接,我需要獲取$ 28的字符串。

我知道scrapy無法處理javascript,並且scrapy.js可用於將js集成到scrapy,但是我不確定在這種情況下是否應該使用它。 無論如何,找到該對象並將其提取到變量中的正確方法是什么。 任何幫助,將不勝感激。 謝謝! [編輯]這是到目前為止的代碼:

bandname = raw_input("Enter a bandname \n")
vs_url = "http://www.vividseats.com/concerts/" + bandname + "-tickets.html"

class MySpider(CrawlSpider):
    handle_httpstatus_list = [416]
    name = 'comparator'
    allowed_domains = ["www.vividseats.com"]
    start_urls = [vs_url]
    tickets_list_xpath = './/*[@itemtype="http://schema.org/Event"]'
def parse_json(self, response):
        loader = response.meta['loader']
        #not sure what to put here yet
        return loader.load_item()

def parse_price(self, response):
        loader = response.meta['loader']
        ticketLink = loader.get_output_value("ticketsLink")
        json_id_list= re.findall(r"\d{2,9}", ticketsLink)
        json_id=  "".join(json_id_list)
        json_url = "www.vividseats.com/javascript/tickets.shtml?productionId=" + json_id
        yield scrapy.Request(json_url, meta={'loader': loader}, callback = self.parse_json, dont_filter = True) 

def parse(self, response):
    """
    """
   selector = HtmlXPathSelector(response)
        # iterate over tickets
        for ticket in selector.select(self.tickets_list_xpath):

            loader = XPathItemLoader(ComparatorItem(), selector=ticket)
            # define loader
            loader.default_input_processor = MapCompose(unicode.strip)
            loader.default_output_processor = Join()
            # iterate over fields and add xpaths to the loader

            loader.add_xpath('eventName' , './/*[@class="productionsEvent"]/text()')
            loader.add_xpath('eventLocation' , './/*[@class = "productionsVenue"]/span[@itemprop  = "name"]/text()')
            loader.add_xpath('ticketsLink' , './/*/a[@class = "btn btn-primary"]/@href')
            loader.add_xpath('eventDate' , './/*[@class = "productionsDate"]/text()')
            loader.add_xpath('eventCity' , './/*[@class = "productionsVenue"]/span[@itemprop  = "address"]/span[@itemprop  = "addressLocality"]/text()')
            loader.add_xpath('eventState' , './/*[@class = "productionsVenue"]/span[@itemprop  = "address"]/span[@itemprop  = "addressRegion"]/text()')
            loader.add_xpath('eventTime' , './/*[@class = "productionsTime"]/text()')
            print "Here is ticket link \n" + loader.get_output_value("ticketsLink")
            ticketsURL = "concerts/" + bandname + "-tickets/" + bandname + "-" + loader.get_output_value("ticketsLink")
            ticketsURL = urljoin(response.url, ticketsURL)
            yield scrapy.Request(ticketsURL, meta={'loader': loader}, callback = self.parse_price, dont_filter = True)

讓我們以這個網址為例;

與上述鏈接相對應的所有票證信息都位於此處 ,從那里您只需要將json的字段映射到html( html頁面中的票證信息 )。

In [1]: ticket_info = jsonresponse.get('tickets')

In [2]: ticket_info
Out[2]: 
 [{u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'1',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB844757004',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'27.00',
  u'q': u'3',
  u'r': u'G2',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'1',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB891598272',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'29.00',
  u'q': u'1',
  u'r': u'G3',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB900500475',
  u'ind': u'0',
  u'l': u'GA MAIN FLOOR',
  u'n': u'',
  u'p': u'30.00',
  u'q': u'2',
  u'r': u'G4',
  u'rhdn': u'0',
  u's': u'GA MAIN F..',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30613',
  u'd': u'3000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB886172318',
  u'ind': u'1',
  u'l': u'GA Second Balcony - Limited View',
  u'n': u'eTicket,Obstructed/Limited View Instant Download.',
  u'p': u'37.00',
  u'q': u'1',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA Second Balcony - Limited View',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'1',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB806449210',
  u'ind': u'1',
  u'l': u'GA MAIN FLOOR',
  u'n': u'eTicket Instant Download.',
  u'p': u'39.00',
  u'q': u'8',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA MAIN F..',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30612',
  u'd': u'2000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB900500473',
  u'ind': u'1',
  u'l': u'GA First Balcony',
  u'n': u'Instant Download.',
  u'p': u'46.00',
  u'q': u'2',
  u'r': u'G3',
  u'rhdn': u'0',
  u's': u'GA First Balcony',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB893201517',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'50.00',
  u'q': u'6',
  u'r': u'G5',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'3',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30615',
  u'd': u'995',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'07/19/15',
  u'i': u'VB900847659',
  u'ind': u'0',
  u'l': u'GA',
  u'n': u'Tickets will be ready for delivery by 07/19/2015.',
  u'p': u'53.00',
  u'q': u'4',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30615',
  u'd': u'995',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'07/19/15',
  u'i': u'VB900847710',
  u'ind': u'0',
  u'l': u'GA',
  u'n': u'Tickets will be ready for delivery by 07/19/2015.',
  u'p': u'53.00',
  u'q': u'3',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30612',
  u'd': u'2000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB900500474',
  u'ind': u'1',
  u'l': u'GA First Balcony',
  u'n': u'Instant Download.',
  u'p': u'57.00',
  u'q': u'8',
  u'r': u'G2',
  u'rhdn': u'0',
  u's': u'GA First Balcony',
  u'sd': u'0',
  u't': u'3',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB880887546',
  u'ind': u'0',
  u'l': u'GA Main Floor',
  u'n': u'eTicket',
  u'p': u'61.00',
  u'q': u'4',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB893198548',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'85.00',
  u'q': u'8',
  u'r': u'G4',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'3',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'0',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB893198623',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'94.00',
  u'q': u'2',
  u'r': u'G4',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'0',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'1',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB844757006',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'88.00',
  u'q': u'8',
  u'r': u'G3',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30615',
  u'd': u'995',
  u'e': u'0',
  u'f': u'0',
  u'g': u'0',
  u'h': u'07/19/15',
  u'i': u'VB793104621',
  u'ind': u'0',
  u'l': u'GA',
  u'n': u'Tickets will be ready for delivery by 07/19/2015.',
  u'p': u'91.00',
  u'q': u'8',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA',
  u'sd': u'0',
  u't': u'3',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'1',
  u'f': u'1',
  u'g': u'0',
  u'h': u'',
  u'i': u'VB844757008',
  u'ind': u'1',
  u'l': u'GA Main Floor',
  u'n': u'Instant Download.',
  u'p': u'111.00',
  u'q': u'8',
  u'r': u'G4',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'1',
  u'v': u'',
  u'z': u'0'},
 {u'c': u'30611',
  u'd': u'1000',
  u'e': u'0',
  u'f': u'0',
  u'g': u'0',
  u'h': u'07/16/15',
  u'i': u'VB791993584',
  u'ind': u'0',
  u'l': u'GA Main Floor',
  u'n': u'Zone Seating. The seller is committing to procure these tickets for you upon receipt of your order. After you place your order and your order is confirmed, we guarantee that your tickets will be within the listed zone or section listed or one comparable and that you will receive these tickets in time for the event or your money back. Orders exceeding four tickets may be split up into different rows within the requested zone or section.',
  u'p': u'170.00',
  u'q': u'6',
  u'r': u'GA',
  u'rhdn': u'0',
  u's': u'GA Main Floor',
  u'sd': u'0',
  u't': u'3',
  u'v': u'',
  u'z': u'1'}]

ticket_info是從低價到高價的票證信息列表。 現在,僅從上面的列表中提取price-info p是對應於機票價格的鑰匙。 利用這些信息,您將獲得類似的信息,

In [3]: price_list = [i.get('p') for i in ticket_info]

In [4]: price_list 
Out[4]: 
[u'27.00',
 u'29.00',
 u'30.00',
 u'37.00',
 u'39.00',
 u'46.00',
 u'50.00',
 u'53.00',
 u'53.00',
 u'57.00',
 u'61.00',
 u'85.00',
 u'94.00',
 u'88.00',
 u'91.00',
 u'111.00',
 u'170.00']

為了確保您獲得最低的價格,您可以執行price_list.sort()並采用其中的第一個元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM