Javascript 如何在scrapy中解析JSON数据

Javascript 如何在scrapy中解析JSON数据,javascript,python,json,web-scraping,scrapy,Javascript,Python,Json,Web Scraping,Scrapy,我已经用Scrapy编写了一个webscraper,它最初会进入网页,为每张票刮取票证信息,并爬行到“票证”按钮重定向到的每个链接。在tickets页面上,为了获得价格,必须请求一个JSON(这现在不是什么问题),文件中的第一个价格需要被提取并保存到一个Scrapy项目加载器中 我尝试使用以下语句在scrapy shell中查找price对象: jsonresponse = json.loads(response.body_as_unicode()) jsonresponse["

我已经用Scrapy编写了一个webscraper,它最初会进入网页,为每张票刮取票证信息,并爬行到“票证”按钮重定向到的每个链接。在tickets页面上,为了获得价格,必须请求一个JSON(这现在不是什么问题),文件中的第一个价格需要被提取并保存到一个Scrapy项目加载器中

我尝试使用以下语句在scrapy shell中查找price对象:

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

但是由于某些原因,他们都没有在文件中找到price对象。如果你看一下,你会发现目前的最低价格是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\u 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\u list.sort()
,并获取其中的第一个元素

你能出示你到目前为止的完整代码吗?
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'}]
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']