163 votes

Scrapy peut-il être utilisé pour extraire du contenu dynamique de sites Web utilisant AJAX?

J'ai été récemment à l'apprentissage de Python et je suis plongeant ma main dans la construction d'un web-grattoir. Il n'est rien de fantaisie à tous; son seul but est d'obtenir les données à partir d'un site de paris et de données mis en Excel.

La plupart des problèmes peuvent être résolus et je suis d'avoir un bon petit mess around. Cependant, je vais frapper un énorme obstacle de plus d'un problème. Si un site se charge d'une table des chevaux et des listes de pari en cours prix cette information n'est pas dans un fichier source. L'idée est que ces données sont en direct parfois, avec les numéros de cours de mise à jour de toute évidence de certains serveur distant. Le code HTML sur mon PC il a tout simplement un trou où leurs serveurs sont en train de pousser à travers toutes les données intéressantes que j'ai besoin.

Maintenant, mon expérience avec le contenu web dynamique est faible, de sorte que cette chose est quelque chose que je vais avoir de la difficulté à obtenir ma tête autour de.

Je pense que Java ou Javascript est une clé, cela apparaît souvent.

Le racloir est simplement un moteur de comparaison de cotes. Certains sites ont des Api, mais j'en ai besoin pour ceux qui n'en ont pas. Je suis à l'aide de la scrapy bibliothèque avec Python 2.7

Je ne m'excuse si cette question est trop vague. En bref, ma question est: comment peut-scrapy être utilisé pour gratter cette dynamique de données afin que je puisse l'utiliser? De sorte que je peux gratter ce pari cotes données en temps réel?

Cheers les gens :)

103voto

Badarau Petru Points 31

Voici un exemple simple d'utilisation de scrapy avec une requête ajax. Laissez-voir le site http://www.rubin-kazan.ru/guestbook.html Tous les messages sont chargés avec une requête ajax. Mon but est de récupérer ce message avec tous leurs attributs (auteur, date, ...).

enter image description here

Lorsque j'analyse le code source de la page je ne peux pas voir tous ces messages parce que la page web utilisation de la technologie ajax. Mais je peux avec Firebug de Mozila Firefox (ou une analogie instrument dans d'autres navigateurs) pour analyser la requête Http qui génèrent les messages sur la page web. enter image description here

Dans ce but, je ne recharge pas la totalité de la page, mais seulement la partie de la page qui contiennent des messages. Pour cela je clique sur un nombre arbitraire de la page sur le fond enter image description hereet j'observe la requête HTTP qui est responsable sur le corps du message enter image description here

Après l'arrivée j'analyse les en-têtes de la requête (je dois citer que cette url, je vais extraire à partir de la source de la page de section var, consultez le code ci-dessous). enter image description here

et la forme de données de contenu de la demande (la méthode Http est "Post")

enter image description here

et le contenu de la réponse, qui est un fichier Json,

enter image description here

qui présente tous les renseignements que je cherche.

À partir de maintenant, je doit mettre en œuvre toutes ces connaissances dans scrapy. Nous allons définir l'araignée à cette fin.

  class spider(BaseSpider):
      name = 'RubiGuesst'
      start_urls = ['http://www.rubin-kazan.ru/guestbook.html']

    def parse(self, response):
      url_list_gb_messages = re.search(r'url_list_gb_messages="(.*)"', response.body).group(1)
      yield FormRequest('http://www.rubin-kazan.ru' + url_list_gb_messages, callback=self.RubiGuessItem, formdata={'page': str(page + 1), 'uid': ''})
    def RubiGuessItem(self, response):
       json_file = response.body

Dans la fonction d'analyse que j'ai la réponse pour la première demande. Dans RubiGuessItem j'ai le fichier json avec toutes les informations.

J'espère que cette réponse vous aidera. En ce qui concerne meilleur.

80voto

Ski Points 5884

Les navigateurs basés sur Webkit (comme Google Chrome ou Safari) a intégré dans les outils de développement. Dans Chrome, vous pouvez l'ouvrir Menu->Tools->Developer Tools. L' Network onglet vous permet de voir toutes les informations au sujet de chaque demande et de la réponse:

enter image description here

Dans le bas de l'image vous pouvez voir que j'ai filtré la demande vers le bas pour XHR - ces demandes sont faites par du code javascript.

Astuce: le journal est effacé à chaque fois que vous chargez une page, au bas de l'image, le point noir bouton de préserver journal.

Après avoir analysé les demandes et les réponses, vous pouvez simuler ces demandes à partir de votre web-crawler et extraire des données. Dans de nombreux cas, il sera plus facile d'obtenir vos données de parsing HTML, parce que les données ne contiennent pas de logique de présentation et formatée pour être accessible par le code javascript.

Que Firefox extension similaire, il est appelé firebug. Certains feront valoir que firebug est encore plus puissant, mais j'aime la simplicité de webkit.

44voto

A T Points 1483

De nombreuses fois lors de l'analyse de problèmes où le contenu qui est affiché sur la page est générée en Javascript et donc scrapy est incapable de ramper pour elle (par exemple. les requêtes ajax, jQuery folie).

Toutefois, si vous utilisez Scrapy avec le web framework de tests de Sélénium, alors nous sommes en mesure d'analyser tout affiché dans un navigateur web normal.

Certaines choses sont à noter:

  • Vous devez avoir la version de Python de Selenium RC installé pour que cela fonctionne, et vous devez avoir configuré le Sélénium correctement. Aussi, c'est juste un modèle de robot. Vous pourriez obtenir beaucoup plus fou et les plus avancées avec des choses, mais je voulais juste montrer l'idée de base. Le code se trouve aujourd'hui vous allez faire deux demandes pour une url. Une demande est faite par Scrapy et l'autre est faite par le Sélénium. Je suis sûr qu'il ya des façons de contourner cela de sorte que vous pourriez peut-être juste prendre le Sélénium faire la seule et unique demande, mais je n'ai pas pris la peine de mettre en œuvre et en faisant deux demandes que vous obtenez à explorer les pages avec Scrapy trop.

  • C'est assez puissant, parce que maintenant vous avez l'ensemble de rendu DOM disponibles pour vous analyser et vous pouvez toujours utiliser toutes les belles ramper fonctionnalités de Scrapy. Cela va faire plus lent ramper, bien sûr, mais selon combien vous avez besoin de l'rendu DOM, il peut être vaut la peine d'attendre.

    from scrapy.contrib.spiders import CrawlSpider, Rule
    from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
    from scrapy.selector import HtmlXPathSelector
    from scrapy.http import Request
    
    from selenium import selenium
    
    class SeleniumSpider(CrawlSpider):
        name = "SeleniumSpider"
        start_urls = ["http://www.domain.com"]
    
        rules = (
            Rule(SgmlLinkExtractor(allow=('\.html', )), callback='parse_page',follow=True),
        )
    
        def __init__(self):
            CrawlSpider.__init__(self)
            self.verificationErrors = []
            self.selenium = selenium("localhost", 4444, "*chrome", "http://www.domain.com")
            self.selenium.start()
    
        def __del__(self):
            self.selenium.stop()
            print self.verificationErrors
            CrawlSpider.__del__(self)
    
        def parse_page(self, response):
            item = Item()
    
            hxs = HtmlXPathSelector(response)
            #Do some XPath selection with Scrapy
            hxs.select('//div').extract()
    
            sel = self.selenium
            sel.open(response.url)
    
            #Wait for javscript to load in Selenium
            time.sleep(2.5)
    
            #Do some crawling of javascript created content with Selenium
            sel.get_text("//div")
            yield item
    
    # Snippet imported from snippets.scrapy.org (which no longer works)
    # author: wynbennett
    # date  : Jun 21, 2011
    

Référence: http://snipplr.com/view/66998/

36voto

rocktheartsm4l Points 176

Une autre solution serait de mettre en place un téléchargement du gestionnaire ou du gestionnaire de téléchargement middleware. L'exemple suivant est un exemple de l'intergiciel en utilisant le sélénium avec headless phantomjs webdriver:

class JsDownload(object):

@check_spider_middleware
def process_request(self, request, spider):
    driver = webdriver.PhantomJS(executable_path='D:\phantomjs.exe')
    driver.get(request.url)
    return HtmlResponse(request.url, encoding='utf-8', body=driver.page_source.encode('utf-8'))

Je voulais capacité à dire les différentes araignées, qui middleware à utiliser, donc j'ai mis en place ce wrapper:

def check_spider_middleware(method):
@functools.wraps(method)
def wrapper(self, request, spider):
    msg = '%%s %s middleware step' % (self.__class__.__name__,)
    if self.__class__ in spider.middleware:
        spider.log(msg % 'executing', level=log.DEBUG)
        return method(self, request, spider)
    else:
        spider.log(msg % 'skipping', level=log.DEBUG)
        return None

return wrapper

settings.py:

DOWNLOADER_MIDDLEWARES = {'MyProj.middleware.MiddleWareModule.MiddleWareClass': 500}

pour wrapper pour travailler toutes les araignées doivent avoir au minimum:

middleware = set([])

pour inclure un middleware:

middleware = set([MyProj.middleware.ModuleName.ClassName])

Le principal avantage de la mise en œuvre de cette manière plutôt que de l'araignée, c'est que vous avez seulement à faire une demande. Dans Un T de la solution par exemple: Le gestionnaire de téléchargement processus de la demande et puis les mains hors de la réponse à l'araignée. L'araignée fait ensuite une nouvelle marque de la demande dans les parse_page fonction -- Que deux demandes pour le même contenu.

Cheers!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X