2016-06-26 7 views
4

Ich versuche, Google Scholar search results zu kriechen und erhalten alle BiBTeX-Format jedes Ergebnis mit der Suche übereinstimmen. Im Moment habe ich einen Scrapy Crawler mit Splash. Ich habe ein Lua-Skript, das auf den Link "Cite" klickt und das modale Fenster lädt, bevor das href des BibTeX-Formats des Zitats abgerufen wird. Da jedoch mehrere Suchergebnisse und somit mehrere "Cite" -Links vorhanden sind, muss ich auf alle klicken und die einzelnen BibTeX-Seiten laden.Splash Lua-Skript, um mehrere Klicks und Besuche zu tun

Hier ist, was ich habe:

import scrapy 
from scrapy_splash import SplashRequest 


class CiteSpider(scrapy.Spider): 
    name = "cite" 
    allowed_domains = ["scholar.google.com", "scholar.google.ae"] 
    start_urls = [ 
     'https://scholar.google.ae/scholar?q="thermodynamics"&hl=en' 
    ] 

    script = """ 
     function main(splash) 
      local url = splash.args.url 
      assert(splash:go(url)) 
      assert(splash:wait(0.5)) 
      splash:runjs('document.querySelectorAll("a.gs_nph[aria-controls=gs_cit]")[0].click()') 
      splash:wait(3) 
      local href = splash:evaljs('document.querySelectorAll(".gs_citi")[0].href') 
      assert(splash:go(href)) 
      return { 
      html = splash:html(), 
      png = splash:png(), 
      href=href, 
      } 
     end 
     """ 

    def parse(self, response): 
     yield SplashRequest(self.start_urls[0], self.parse_bib, 
          endpoint="execute", 
          args={"lua_source": self.script}) 

    def parse_bib(self, response): 
     filename = response.url.split("/")[-2] + '.html' 
     with open(filename, 'wb') as f: 
      f.write(response.css("body > pre::text").extract()[0]) 

Ich denke, ich sollte den Index der „Cité“ Link in das Lua Script übergeben, wenn ich den querySelectorAll Anruf durchführen, aber ich kann nicht scheinen zu finden, Möglichkeit, eine andere Variable an die Funktion zu übergeben. Auch ich nehme an, dass ich etwas schmutziges Javascript history.back() tun muss, um zurück zu der ursprünglichen Resultatseite zurückzukommen, nachdem ich das BibTeX besorgte, aber ich fühle, dass es eine elegantere Weise gibt, damit umzugehen.

Antwort

0

Okay, also habe ich eine Lösung gehackt, die funktioniert. Zunächst einmal werden wir das Lua Script müssen wandelbar sein, so werden wir es mit einer Funktion machen:

def script(n): 
    _script = """ 
     function main(splash) 
      local url = splash.args.url 
      local href = "" 
      assert(splash:go(url)) 
      assert(splash:wait(0.5)) 
      splash:runjs('document.querySelectorAll("a.gs_nph[aria-controls=gs_cit]")[{}].click()') 
      splash:wait(3) 
      href = splash:evaljs('document.querySelectorAll("a.gs_citi")[0].href') 
      assert(splash:go(href)) 
      return {} 
     end 
     """.format(n, "{html=splash:html(),png=splash:png(), href=href,}") 
    return _script 

Ich musste dann die parse Funktion so modifizieren, dass sie alle „Cite“ Links auf der Seite klickt . Die Methode besteht darin, alle übereinstimmenden "Cite" -Links auf der Seite zu durchlaufen und auf jede einzeln zu klicken. Ich habe das Lua-Skript gemacht, um die Seite erneut zu laden (was schmutzig ist, aber ich kann mir keinen anderen Weg vorstellen) und klicke auf den Index des angefragten "Cite" -Links. Auch sie hat doppelte Anforderungen damit zu machen, warum die dont_filter=True gibt es:

def parse(self, response): 
     n = len(response.css("a.gs_nph[aria-controls=gs_cit]").extract()) 
     for i in range(n): 
      yield SplashRequest(response.url, self.parse_bib, 
           endpoint="execute", 
           args={"lua_source": script(i)}, 
           dont_filter=True) 

Hoffnung, das hilft.

+3

FYI: Sie können "n" -Argument in 'SplashRequest (..., args = {" lua_source ": script," n ": n})' übergeben und dann von einem Skript als 'splash.args 'darauf zugreifen .n'. Auf diese Weise wird die Formatierung von Zeichenfolgen nicht benötigt. String Formatierung hat mehrere Nachteile - es ist mehr Code, Sie müssen Werte als gültige Lua (n/a für Integer-Variablen) zu entkommen, und es spielt nicht gut mit Caching (Splash kann Skripte cachen, so dass es keine Notwendigkeit gibt um bei jeder Anfrage ein Skript zu senden). –

Verwandte Themen