2015-03-22 4 views
0

У меня есть spider (нажмите, чтобы посмотреть источник), который отлично работает для регулярной очистки страницы html. Однако я хочу добавить дополнительную функцию. Я хотел бы проанализировать страницу JSON.Scrapy: Как я могу разобрать ответ JSON?

Вот что я хочу сделать (здесь это делается вручную, без Scrapy):

import requests, json 
import datetime 

def main(): 
    user_agent = { 
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36' 
    } 

    # This is the URL that outputs JSON: 
    externalj = 'http://www.thestudentroom.co.uk/externaljson.php?&s=' 
    # Form the end of the URL, it is based on the time (unixtime): 

    past = datetime.datetime.now() - datetime.timedelta(minutes=15) 
    time = past.strftime('%s') 
    # This is the full URL: 
    url = externalj + time 

    # Make the HTTP get request: 
    tsr_data = requests.get(url, headers= user_agent).json() 

    # Iterate over the json data and form the URLs 
    # (there are no URLs at all in the JSON data, they must be formed manually): 

    # URL is formed simply by concatenating the canonical link with a thread-id: 

    for post in tsr_data['discussions-recent']: 
     link= 'www.thestudentroom.co.uk/showthread.php?t=' 
     return link + post['threadid'] 

Эта функция возвращает соответствующие ссылки на HTML-страницах (ссылки на темы форума), что я хочу, чтобы очистить , Кажется, мне нужно будет создать свой собственный объект запроса для отправки в parse_link в spider?

Мой вопрос: где я могу поставить этот код? Я очень смущен относительно того, как включить это в scrapy? Нужно ли мне создавать другого паука?

В идеале, мне бы хотелось, чтобы он работал с the spider that I already have, не уверен, что это возможно.

Очень смущен относительно того, как реализовать это в терапии. Надеюсь, кто-то может посоветовать!

Мой текущий паук это:

import scrapy 
from tutorial.items import TsrItem 
from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors import LinkExtractor 

class TsrSpider(CrawlSpider): 
    name = 'tsr' 
    allowed_domains = ['thestudentroom.co.uk'] 

    start_urls = ['http://www.thestudentroom.co.uk/forumdisplay.php?f=89'] 

    download_delay = 2 
    user_agent = 'youruseragenthere' 

    thread_xpaths = ("//tr[@class='thread unread ']", 
      "//*[@id='discussions-recent']/li/a", 
      "//*[@id='discussions-popular']/li/a") 

    rules = [ 
     Rule(LinkExtractor(allow=('showthread\.php\?t=\d+',), 
      restrict_xpaths=thread_xpaths), 
     callback='parse_link', follow=True),] 

    def parse_link(self, response): 
     for sel in response.xpath("//li[@class='post threadpost old ']"): 
      item = TsrItem() 
      item['id'] = sel.xpath(
"div[@class='post-header']//li[@class='post-number museo']/a/span/text()").extract() 
      item['rating'] = sel.xpath(
"div[@class='post-footer']//span[@class='score']/text()").extract() 
      item['post'] = sel.xpath(
"div[@class='post-content']/blockquote[@class='postcontent restore']/text()").extract() 
      item['link'] = response.url 
      item['topic'] = response.xpath(
"//div[@class='forum-header section-header']/h1/span/text()").extract() 
      yield item 
+0

Вы видели [этот предыдущий SO post] (https://stackoverflow.com/questions/18171835/scraping- а-JSON-ответ-с-Scrapy)? Возможно, это может ответить на ваш вопрос. – oldmandrum

+0

Да, я это видел.Только это не может быть связано с моим нынешним пауком. Согласно документам, метод анализа CrawlSpider не должен изменяться. – BBedit

ответ

0

ли ссылки всегда следуют в том же формате? Не удалось ли создать новое правило для JSON-ссылок с отдельной функцией parse_json, используемой в качестве обратного вызова?

+0

Ссылки соответствуют одному и тому же формату. Но на самой странице JSON нет ссылок. – BBedit

1

Это кажется Я нашел способ заставить его работать. И, может быть, мой оригинальный пост не ясен.

Я хотел разобрать ответ JSON, а затем отправить запрос для дальнейшей обработки с помощью scrapy.

Я добавил следующее к моему Spider:

# A request object is required. 
from scrapy.http import Request 

И:

def parse_start_url(self, response): 
    if 'externaljson.php' in str(response.url): 
     return self.make_json_links(response) 

parse_start_url, кажется, делает, как он говорит. Он анализирует исходные URL-адреса (запускать URL-адреса). Здесь нужно обрабатывать только страницу JSON.

Из-за этого мне нужно, чтобы добавить свой специальный формат JSON URL с моей HTML URLs:

start_urls = ['http://tsr.com/externaljson.php', 'http://tsr.com/thread.html'] 

мне теперь нужно сгенерировать URL, в форме запроса, от réponse страницы JSON в:

def make_json_links(self, response): 
    ''' Creates requests from JSON page. ''' 
    data = json.loads(response.body_as_unicode()) 
    for post in data['discussions-recent']: 
     link = 'http://www.tsr.co.uk/showthread.php?t=' 
     full_link = link + str(post['threadid']) 
     json_request = Request(url=full_link) 
     return json_request 

И теперь это работает. Тем не менее, я уверен, что это хакерский и неэлегантный способ добиться этого. Он чувствует себя как-то не так.

Он работает, и он следует всем ссылкам, которые я сделал на странице JSON. Я также не уверен, что я должен был использовать yield вместо return где-то там ...

Смежные вопросы