2017-03-01 3 views
0

Je travaille sur un code plus grand qui affichera les liens des résultats pour une recherche Google Newspaper et ensuite analyser ces liens pour certains mots-clés et le contexte et les données. J'ai tout ce travail à faire, et maintenant, quand j'essaie de parcourir les pages de résultats, j'arrive à un problème. Je ne suis pas sûr de savoir comment faire cela sans API, que je ne sais pas comment utiliser. Je dois juste pouvoir parcourir plusieurs pages de résultats de recherche pour pouvoir ensuite appliquer mon analyse. Il semble qu'il existe une solution simple pour parcourir les pages de résultats, mais je ne le vois pas.Python itérer à travers les pages de recherche google

Y a-t-il des suggestions sur les façons d'aborder ce problème? Je suis un peu nouveau à Python et j'ai appris toutes ces techniques de raclage, donc je ne suis pas sûr si je manque quelque chose de simple ici. Je sais que cela peut être un problème avec Google restreindre les recherches automatisées, mais même en tirant dans la première centaine de liens serait bénéfique. J'ai vu des exemples de cela à partir de recherches Google classiques, mais pas à partir de recherches Google Journal

Voici le corps du code. S'il y a des lignes où vous avez des suggestions, ce serait utile. Merci d'avance!

def get_page_tree(url): 
page = requests.get(url=url, verify=False) 
return html.fromstring(page.text) 

def find_other_news_sources(initial_url): 
    forwarding_identifier = '/url?q=' 
    google_news_search_url = "https://www.google.com/search?hl=en&gl=us&tbm=nws&authuser=0&q=ohio+pay-to-play&oq=ohio+pay-to-play&gs_l=news-cc.3..43j43i53.2737.7014.0.7207.16.6.0.10.10.0.64.327.6.6.0...0.0...1ac.1.NAJRCoza0Ro" 
    google_news_search_tree = get_page_tree(url=google_news_search_url) 
    other_news_sources_links = [a_link.replace(forwarding_identifier, '').split('&')[0] for a_link in google_news_search_tree.xpath('//a//@href') if forwarding_identifier in a_link] 
    return other_news_sources_links 

links = find_other_news_sources("https://www.google.com/search? hl=en&gl=us&tbm=nws&authuser=0&q=ohio+pay-to-play&oq=ohio+pay-to-play&gs_l=news-cc.3..43j43i53.2737.7014.0.7207.16.6.0.10.10.0.64.327.6.6.0...0.0...1ac.1.NAJRCoza0Ro") 

with open('textanalysistest.csv', 'wt') as myfile: 
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) 
    for row in links: 
     print(row) 

Répondre

0

Je suis à la recherche dans la construction d'un analyseur syntaxique pour un site avec une structure similaire à celle de Google (à savoir un groupe de pages de résultats consécutifs, chacun avec une table des matières d'intérêt).

Une combinaison du package Selenium (pour la navigation de site basée sur les éléments de page) et BeautifulSoup (pour l'analyse HTML) semble être l'arme de choix pour récolter du contenu écrit. Vous les trouverez peut-être utiles, même si je n'ai aucune idée du type de défense que Google a mis en place pour empêcher le raclage.

Une implémentation possible pour Mozilla Firefox en utilisant le sélénium, beautifulsoup et geckodriver:

from bs4 import BeautifulSoup, SoupStrainer 
from bs4.diagnose import diagnose 
from os.path import isfile 
from time import sleep 
import codecs 
from selenium import webdriver 

def first_page(link): 
    """Takes a link, and scrapes the desired tags from the html code""" 
    driver = webdriver.Firefox(executable_path = 'C://example/geckodriver.exe')#Specify the appropriate driver for your browser here 
    counter=1 
    driver.get(link) 
    html = driver.page_source 
    filter_html_table(html) 
    counter +=1 
    return driver, counter 


def nth_page(driver, counter, max_iter): 
    """Takes a driver instance, a counter to keep track of iterations, and max_iter for maximum number of iterations. Looks for a page element matching the current iteration (how you need to program this depends on the html structure of the page you want to scrape), navigates there, and calls mine_page to scrape.""" 
    while counter <= max_iter: 
     pageLink = driver.find_element_by_link_text(str(counter)) #For other strategies to retrieve elements from a page, see the selenium documentation 
     pageLink.click() 
     scrape_page(driver) 
     counter+=1 
    else: 
     print("Done scraping") 
    return 


def scrape_page(driver): 
    """Takes a driver instance, extracts html from the current page, and calls function to extract tags from html of total page""" 
    html = driver.page_source #Get html from page 
    filter_html_table(html) #Call function to extract desired html tags 
    return 


def filter_html_table(html): 
    """Takes a full page of html, filters the desired tags using beautifulsoup, calls function to write to file""" 
    only_td_tags = SoupStrainer("td")#Specify which tags to keep 
    filtered = BeautifulSoup(html, "lxml", parse_only=only_td_tags).prettify() #Specify how to represent content 
    write_to_file(filtered) #Function call to store extracted tags in a local file. 
    return 


def write_to_file(output): 
    """Takes the scraped tags, opens a new file if the file does not exist, or appends to existing file, and writes extracted tags to file.""" 
    fpath = "<path to your output file>" 
    if isfile(fpath): 
     f = codecs.open(fpath, 'a') #using 'codecs' to avoid problems with utf-8 characters in ASCII format. 
     f.write(output) 
     f.close() 
    else: 
     f = codecs.open(fpath, 'w') #using 'codecs' to avoid problems with utf-8 characters in ASCII format. 
     f.write(output) 
     f.close() 
    return 

Après cela, il est juste une question d'appeler:

link = <link to site to scrape> 
driver, n_iter = first_page(link) 
nth_page(driver, n_iter, 1000) # the 1000 lets us scrape 1000 of the result pages 

Notez que ce script suppose que le résultat Les pages que vous essayez d'extraire sont numérotées séquentiellement, et ces numéros peuvent être récupérés à partir du code HTML de la page en utilisant 'find_element_by_link_text'. Pour d'autres stratégies permettant de récupérer des éléments d'une page, voir la documentation du sélénium here. De plus, notez que vous devez télécharger les paquets dont cela dépend, et le pilote dont le sélénium a besoin pour parler avec votre navigateur (dans ce cas geckodriver, téléchargez geckodriver, placez-le dans un dossier, puis référez-vous Si vous finissez par utiliser ces paquetages, il peut être utile de répartir vos requêtes serveur en utilisant le paquet time (natif de python) pour éviter de dépasser le nombre maximum de requêtes autorisées pour le paquet exécutable (dans l'exécutable 'executable_path')

serveur hors duquel vous grattez. Je n'ai pas fini par en avoir besoin pour mon propre projet, mais voir here, deuxième réponse à la question initiale, pour un exemple d'implémentation avec le module de temps utilisé dans le quatrième bloc de code.

Yeeeeaaaahhh ... Si quelqu'un avec un rep supérieur pouvait éditer et ajouter des liens vers des documentations sur le magnétoscope, le sélénium et le temps, ce serait génial.