2016-02-15 11 views
5

Per favore, sopportami. Sono abbastanza nuovo in Python - ma mi diverto molto. Sto cercando di codificare un web crawler che striscia attraverso i risultati elettorali dell'ultimo referendum in Danimarca. Sono riuscito a estrarre tutti i collegamenti rilevanti dalla pagina principale. E ora voglio che Python segua ognuno dei 92 link e raccolga 9 pezzi di informazione da ognuna di quelle pagine. Ma sono così bloccato. Spero che tu possa darmi un suggerimento.Web crawler - seguenti link

Ecco il mio codice:

import requests 
import urllib2 
from bs4 import BeautifulSoup 

# This is the original url http://www.kmdvalg.dk/ 

soup = BeautifulSoup(urllib2.urlopen('http://www.kmdvalg.dk/').read()) 

my_list = [] 
all_links = soup.find_all("a") 

for link in all_links: 
    link2 = link["href"] 
    my_list.append(link2) 

for i in my_list[1:93]: 
    print i 

# The output shows all the links that I would like to follow and gather information from. How do I do that? 
+0

Puoi menzionare più informazioni su 9 pezzi che vuoi inserire all'interno di ciascun link? – titipata

+0

Wow - voi ragazzi siete fantastici !! Dovrò passare un po 'di tempo a cercare di capire le tue soluzioni. Tornerò non appena li capirò. MOLTE GRAZIE! – Metods

+0

@titipat: Sì. Dai un'occhiata a questo sito secondario. Voglio afferrare "stemmeberettigede/numero di persone che possono votare", "Optalte stemmer/voti contati", "JA-stemmer/Persone che votano sì", "NEJ-stemmer/persone che hanno votato no", "Blanke stemmer/blank voti "," Ugyldige stemmer/voti invalidi "e il nome del comune (Assenskredsen in questo caso) – Metods

risposta

4

Un approccio semplice sarebbe quello di scorrere l'elenco di URL e loro ogni analizzare singolarmente:

for url in my_list: 
    soup = BeautifulSoup(urllib2.urlopen(url).read()) 
    # then parse each page individually here 

In alternativa, si potrebbe accelerare le cose in modo significativo utilizzando Futures.

from requests_futures.sessions import FuturesSession 

def my_parse_function(html): 
    """Use this function to parse each page""" 
    soup = BeautifulSoup(html) 
    all_paragraphs = soup.find_all('p') 
    return all_paragraphs 

session = FuturesSession(max_workers=5) 
futures = [session.get(url) for url in my_list] 

page_results = [my_parse_function(future.result()) for future in results] 
+0

Questo è semplicemente fantastico. La mia sceneggiatura ora funziona grazie al tuo commento sull'iterazione del mio elenco di URL. – Metods

+0

UPS - non è stato fatto. Sono sicuro che tutti gli altri suggerimenti su questa pagina sono più interessanti - ma ho scelto la pace dei consigli che potrei capire. Grazie. Questo è il mio codice finale che funziona - se hai suggerimenti per renderlo più intelligente per favore fammi sapere. Cordiali saluti dai metodi. – Metods

5

Ecco la mia soluzione utilizzando lxml. E 'simile a BeautifulSoup

import lxml 
from lxml import html 
import requests 

page = requests.get('http://www.kmdvalg.dk/main') 
tree = html.fromstring(page.content) 
my_list = tree.xpath('//div[@class="LetterGroup"]//a/@href') # grab all link 
print 'Length of all links = ', len(my_list) 

my_list è una lista consiste di tutti i collegamenti. E ora puoi usare il ciclo per raccogliere informazioni all'interno di ciascuna pagina.

Possiamo eseguire il ciclo di ogni collegamento. All'interno di ciascuna pagina, puoi estrarre le informazioni come esempio. Questo è solo per il tavolo in alto.

table_information = [] 
for t in my_list: 
    page_detail = requests.get(t) 
    tree = html.fromstring(page_detail.content) 
    table_key = tree.xpath('//td[@class="statusHeader"]/text()') 
    table_value = tree.xpath('//td[@class="statusText"]/text()') + tree.xpath('//td[@class="statusText"]/a/text()') 
    table_information.append(zip([t]*len(table_key), table_key, table_value)) 

Per tabella seguente pagina,

table_information_below = [] 
for t in my_list: 
    page_detail = requests.get(t) 
    tree = html.fromstring(page_detail.content) 
    l1 = tree.xpath('//tr[@class="tableRowPrimary"]/td[@class="StemmerNu"]/text()') 
    l2 = tree.xpath('//tr[@class="tableRowSecondary"]/td[@class="StemmerNu"]/text()') 
    table_information_below.append([t]+l1+l2) 

Spero che questo aiuto!

2

Questa sarebbe la mia soluzione al vostro problema

import requests 
from bs4 import BeautifulSoup 


def spider(): 
    url = "http://www.kmdvalg.dk/main" 
    source_code = requests.get(url) 
    plain_text = source_code.text 
    soup = BeautifulSoup(plain_text, 'html.parser') 

    for link in soup.findAll('div', {'class': 'LetterGroup'}): 
     anc = link.find('a') 
     href = anc.get('href') 

     print(anc.getText()) 
     print(href) 
     # spider2(href) call a second function from here that is similar to this one(making url = to herf) 
     spider2(href) 
     print("\n") 


def spider2(linktofollow): 
    url = linktofollow 
    source_code = requests.get(url) 
    plain_text = source_code.text 
    soup = BeautifulSoup(plain_text, 'html.parser') 

    for link in soup.findAll('tr', {'class': 'tableRowPrimary'}): 
     anc = link.find('td') 

     print(anc.getText()) 
    print("\n") 


spider() 

la sua non è fatto ... ho solo un elemento semplice dal tavolo, ma si ottiene l'idea e come la sua presunta lavorare.

+0

invece di trovare ('td') nella seconda possibilità puoi usare findAll usando il nome della classe di td che vuoi trovare. – CVasquezG

1

Ecco il mio codice finale che funziona senza problemi. Per favore fatemi sapere se avrei potuto farlo in modo più intelligente!

import urllib2 
from bs4 import BeautifulSoup 
import codecs 

f = codecs.open("eu2015valg.txt", "w", encoding="iso-8859-1") 

soup = BeautifulSoup(urllib2.urlopen('http://www.kmdvalg.dk/').read()) 

liste = [] 

alle_links = soup.find_all("a") 

for link in alle_links: 
    link2 = link["href"] 
    liste.append(link2) 

for url in liste[1:93]: 
    soup = BeautifulSoup(urllib2.urlopen(url).read().decode('iso-8859-1')) 
    tds = soup.findAll('td') 
    stemmernu = soup.findAll('td', class_='StemmerNu') 
    print >> f, tds[5].string,";",tds[12].string,";",tds[14].string,";",tds[16].string,";", stemmernu[0].string,";",stemmernu[1].string,";",stemmernu[2].string,";",stemmernu[3].string,";",stemmernu[6].string,";",stemmernu[8].string,";",'\r\n' 

f.close()