2010-01-17 20 views
172

Mi piacerebbe prendere i tempi di alba/tramonto ogni giorno da un sito web. È possibile raschiare il contenuto Web con Python? quali sono i moduli utilizzati? C'è qualche tutorial disponibile?Web scraping con Python

+3

Python offre diverse opzioni per lo scraping web. Ho elencato alcune delle opzioni [qui] (http://stackoverflow.com/questions/2861/options-for-html-scraping/1970411#1970411) in risposta a una domanda simile. – filippo

+0

Perché non usare semplicemente il parser HTML integrato nella libreria standard Python? Certamente per un compito così semplice e poco frequente (solo una volta al giorno), vedo poche ragioni per cercare altri strumenti. https://docs.python.org/2.7/library/htmlparser.html – ArtOfWarfare

+0

Spero che questo post possa essere utile a qualcuno per quanto riguarda questo. Un buon tutorial per un principiante. http://samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Usa una bella libreria di python per il web scraping con python. –

risposta

181

Usa urllib2 in combinazione con il brillante BeautifulSoup libreria:

import urllib2 
from BeautifulSoup import BeautifulSoup 
# or if you're using BeautifulSoup4: 
# from bs4 import BeautifulSoup 

soup = BeautifulSoup(urllib2.urlopen('http://example.com').read()) 

for row in soup('table', {'class': 'spad'})[0].tbody('tr'): 
    tds = row('td') 
    print tds[0].string, tds[1].string 
    # will print date and sunrise 
+4

Piccolo commento: questo può essere leggermente semplificato utilizzando il pacchetto richieste sostituendo la riga 6 con: soup = BeautifulSoup (requests.get ('http://example.com') .text) –

+2

grazie per il suggerimento. il pacchetto di richiesta non esisteva ancora, quando ho scritto lo snippet sopra ;-) –

+0

@DerrickCoetzee - la tua semplificazione solleva un errore di MissingSchema (almeno sulla mia installazione). Funziona: 'soup = BeautifulSoup (requests.get ('http://example.com') .text)' – kmote

7

È possibile utilizzare urllib2 per effettuare le richieste HTTP e quindi disporre di contenuto Web.

È possibile ottenere in questo modo:

import urllib2 
response = urllib2.urlopen('http://example.com') 
html = response.read() 

Beautiful Soup è un parser HTML pitone che si suppone sia un bene per screen scraping.

In particolare, here è il loro tutorial sull'analisi di un documento HTML.

Buona fortuna!

+0

Potrebbe essere un'idea impostare un massimo sui byte letti. risposta.leggi (100000000) o qualcosa così quegli URL per ISO non riempiono la tua RAM. Estrazione felice. –

16

ho raccolto insieme gli script dal mio web scraping lavoro in this library.

Esempio di script per il vostro caso:

from webscraping import download, xpath 
D = download.Download() 

html = D.get('http://example.com') 
for row in xpath.search(html, '//table[@class="spad"]/tbody/tr'): 
    cols = xpath.search(row, '/td') 
    print 'Sunrise: %s, Sunset: %s' % (cols[1], cols[2]) 

uscita:

Sunrise: 08:39, Sunset: 16:08 
Sunrise: 08:39, Sunset: 16:09 
Sunrise: 08:39, Sunset: 16:10 
Sunrise: 08:40, Sunset: 16:10 
Sunrise: 08:40, Sunset: 16:11 
Sunrise: 08:40, Sunset: 16:12 
Sunrise: 08:40, Sunset: 16:13 
59

Consiglio vivamente Scrapy, per motivi in ​​corso di elaborazione in this question - "Is it worth learning Scrapy?".

Citato dalla risposta:

  • Scrapy scansione è più veloce di meccanizzare usa perché le operazioni asincrone (in cima Twisted).
  • Scrapy offre un supporto migliore e più veloce per l'analisi (x) html su libxml2.
  • Scrapy è un framework maturo con piena unicode, gestisce le redirezioni, risposte compressi con gzip, codifiche dispari, cache http integrato, ecc
  • Una volta che siete in Scrapy, è possibile scrivere un ragno in meno di 5 minuti in cui scaricare le immagini, crea miniature ed esporta direttamente i dati estratti in csv o json.
+12

Non ho notato che questa domanda aveva già 2 anni, sento ancora che Scrapy dovrebbe essere nominato qui nel caso in cui qualcun altro abbia la stessa domanda. –

+4

Scrapy è un framework, e quindi è orribile e pensa che sia più importante del tuo progetto. È un framework a causa delle limitazioni orribili (non necessarie) di Twisted. – user1244215

+4

@ user1244215: È un framework perché i framework sono belli. Se non vuoi usarlo come framework, non c'è nulla che ti impedisca di bloccare tutto il tuo codice in un unico file. – Blender

4

io uso una combinazione di Scrapemark (URL trovare - PY2) e httlib2 (download delle immagini - PY2 + 3). Scrapemark.py ha 500 righe di codice, ma usa espressioni regolari, quindi potrebbe non essere così veloce, non testare.

Esempio per raschiare il vostro sito web:

import sys 
from pprint import pprint 
from scrapemark import scrape 

pprint(scrape(""" 
    <table class="spad"> 
     <tbody> 
      {* 
       <tr> 
        <td>{{[].day}}</td> 
        <td>{{[].sunrise}}</td> 
        <td>{{[].sunset}}</td> 
        {# ... #} 
       </tr> 
      *} 
     </tbody> 
    </table> 
""", url=sys.argv[1])) 

Usage:

python2 sunscraper.py http://www.example.com/ 

Risultato:

[{'day': u'1. Dez 2012', 'sunrise': u'08:18', 'sunset': u'16:10'}, 
{'day': u'2. Dez 2012', 'sunrise': u'08:19', 'sunset': u'16:10'}, 
{'day': u'3. Dez 2012', 'sunrise': u'08:21', 'sunset': u'16:09'}, 
{'day': u'4. Dez 2012', 'sunrise': u'08:22', 'sunset': u'16:09'}, 
{'day': u'5. Dez 2012', 'sunrise': u'08:23', 'sunset': u'16:08'}, 
{'day': u'6. Dez 2012', 'sunrise': u'08:25', 'sunset': u'16:08'}, 
{'day': u'7. Dez 2012', 'sunrise': u'08:26', 'sunset': u'16:07'}] 
10

Vorrei suggerire check-out pyquery.Usa la sintassi jquery-like (aka css-like) che rende le cose veramente facili per chi viene da quello sfondo.

Per il vostro caso, sarebbe qualcosa di simile:

from pyquery import * 

html = PyQuery(url='http://www.example.com/') 
trs = html('table.spad tbody tr') 

for tr in trs: 
    tds = tr.getchildren() 
    print tds[1].text, tds[2].text 

uscita:

5:16 AM 9:28 PM 
5:15 AM 9:30 PM 
5:13 AM 9:31 PM 
5:12 AM 9:33 PM 
5:11 AM 9:34 PM 
5:10 AM 9:35 PM 
5:09 AM 9:37 PM 
2

Ho appena visto RoboBrowser in Pycoder's Weekly.

Una libreria per il web scraping basata su Requests e BeautifulSoup. Come Mechanize, ma con test, documenti e un'interfaccia Pythonic.

2

Il framework open source di scrapbook aiuterà gli scrap Web in python. Questo framework open source e collaborativo per l'estrazione dei dati necessari dai siti Web.

Lo scraping Web è strettamente correlato all'indicizzazione del Web, che indicizza le informazioni sul Web utilizzando un bot o un web crawler ed è una tecnica universale adottata dalla maggior parte dei motori di ricerca.

More About Web Scraping

+0

Vedi [http://scrapy.org/](http://scrapy.org/) –

1

di semplificare la vita utilizzando CSS Selectors

So che sono venuto in ritardo alla festa, ma ho un bel suggerimento per voi.

Utilizzando BeautifulSoup è già stato suggerito vorrei piuttosto preferisce usare CSS Selectors per raschiare dati all'interno HTML

import urllib2 
from bs4 import BeautifulSoup 

main_url = "http://www.example.com" 

main_page_html = tryAgain(main_url) 
main_page_soup = BeautifulSoup(main_page_html) 

# Scrape all TDs from TRs inside Table 
for tr in main_page_soup.select("table.class_of_table"): 
    for td in tr.select("td#id"): 
     print(td.text) 
     # For acnhors inside TD 
     print(td.select("a")[0].text) 
     # Value of Href attribute 
     print(td.select("a")[0]["href"]) 

# This is method that scrape URL and if it doesnt get scraped, waits for 20 seconds and then tries again. (I use it because my internet connection sometimes get disconnects) 
def tryAgain(passed_url): 
    try: 
     page = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text 
     return page 
    except Exception: 
     while 1: 
      print("Trying again the URL:") 
      print(passed_url) 
      try: 
       page = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text 
       print("-------------------------------------") 
       print("---- URL was successfully scraped ---") 
       print("-------------------------------------") 
       return page 
      except Exception: 
       time.sleep(20) 
       continue 
0

Ecco un semplice web crawler, ho usato BeautifulSoup e cercheremo tutti i collegamenti (tasselli) che è il nome della classe è _3NFO0d. Ho usato Flipkar.com, è un negozio di vendita online.

import requests 
from bs4 import BeautifulSoup 
def crawl_flipkart(): 
    url = 'https://www.flipkart.com/' 
    source_code = requests.get(url) 
    plain_text = source_code.text 
    soup = BeautifulSoup(plain_text, "lxml") 
    for link in soup.findAll('a', {'class': '_3NFO0d'}): 
     href = link.get('href') 
     print(href) 

crawl_flipkart() 
0

Se pensiamo di ottenere nome di elementi da qualsiasi categoria specifica, allora possiamo farlo specificando il nome della classe di tale categoria con il selettore css:

import requests ; from bs4 import BeautifulSoup 

soup = BeautifulSoup(requests.get('https://www.flipkart.com/').text, "lxml") 
for link in soup.select('div._2kSfQ4'): 
    print(link.text) 

Questo è il risultato della ricerca parziali:

Puma, USPA, Adidas & moreUp to 70% OffMen's Shoes 
Shirts, T-Shirts...Under ₹599For Men 
Nike, UCB, Adidas & moreUnder ₹999Men's Sandals, Slippers 
Philips & moreStarting ₹99LED Bulbs & Emergency Lights 
0

Nuova risposta a questa domanda. lxml è emerso come il modo preferito per fare scraping web in Python. Non ha dipendenza da Twisted a differenza di scrapy. Anche approvato dal Hitchhiker's guide to Python.