Web scraping con Python [cerrado]

183

Me gustaría obtener las horas diarias de amanecer / atardecer desde un sitio web. ¿Es posible raspar contenido web con Python? ¿Cuáles son los módulos utilizados? ¿Hay algún tutorial disponible?

eozzy
fuente
3
Python tiene varias opciones para el raspado web. Enumeré algunas de las opciones aquí en respuesta a una pregunta similar.
filippo
¿Por qué no usar el analizador HTML incorporado en la biblioteca estándar de Python? Ciertamente, para una tarea tan simple e infrecuente (solo una vez al día), veo pocas razones para buscar otras herramientas. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare
Espero que esta publicación pueda ser útil para alguien con respecto a esto. Un buen tutorial para principiantes. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Utiliza la hermosa biblioteca de sopa de python para el raspado web con python.
Samitha Chathuranga

Respuestas:

187

Use urllib2 en combinación con la brillante biblioteca BeautifulSoup :

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
lesmana
fuente
77
Pequeño comentario: esto puede simplificarse un poco usando el paquete de solicitudes reemplazando la línea 6 con: soup = BeautifulSoup (request.get (' example.com'). Text )
D Coetzee
44
gracias por el consejo. el paquete de solicitud aún no existía, cuando escribí el fragmento de arriba ;-)
1
@DerrickCoetzee: su simplificación genera un error MissingSchema (al menos en mi instalación). Esto funciona:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote
@kmote: eso fue lo que escribí pero olvidé backticksel código y lo convirtió en un enlace. ¡Gracias!
D Coetzee
¿Cómo estás seguro de que el contenido estará en td y tr. Puede estar en ul y li también ¿verdad?
Shashank Hegde
62

Realmente recomiendo Scrapy.

Cita de una respuesta eliminada:

  • El rastreo irregular es más rápido que el mecanizado porque utiliza operaciones asincrónicas (además de Twisted).
  • Scrapy tiene un soporte mejor y más rápido para analizar (x) html sobre libxml2.
  • Scrapy es un marco maduro con unicode completo, maneja redirecciones, respuestas comprimidas, codificaciones extrañas, caché http integrado, etc.
  • Una vez que esté en Scrapy, puede escribir una araña en menos de 5 minutos que descargue imágenes, cree miniaturas y exporte los datos extraídos directamente a csv o json.
Sjaak Trekhaak
fuente
13
No noté que esta pregunta ya tenía 2 años, todavía siento que Scrapy debería nombrarse aquí en caso de que alguien más tenga la misma pregunta.
Sjaak Trekhaak
44
Scrapy es un marco y, por lo tanto, es horrible y cree que es más importante que tu proyecto. Es un marco debido a las horribles (innecesarias) limitaciones de Twisted.
user1244215
44
@ user1244215: Es un marco porque los marcos son buenos. Si no desea usarlo como marco, no hay nada que le impida atascar todo su código en un solo archivo.
Blender
1
Pero no es compatible con Python 3.x.
17

Reuní scripts de mi trabajo de raspado web en esta biblioteca de bit-bucket .

Script de ejemplo para su 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])

Salida:

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
hoju
fuente
10

Sugeriría encarecidamente visitar pyquery . Utiliza una sintaxis similar a jquery (también conocida como css) que hace que las cosas sean realmente fáciles para aquellos que provienen de ese entorno.

Para su caso, sería algo como:

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

Salida:

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
scottmrogowski
fuente
7

Puede usar urllib2 para realizar las solicitudes HTTP, y luego tendrá contenido web.

Puedes obtenerlo así:

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

Hermosa sopa es un analizador HTML de Python que se supone que es bueno para el raspado de pantalla.

En particular, aquí está su tutorial sobre el análisis de un documento HTML.

¡Buena suerte!

danben
fuente
Puede ser una idea establecer un máximo en los bytes leídos. response.read (100000000) o algo así para que esas URL para ISO no llenen tu RAM. Feliz minería
Andrew Paté
4

Yo uso una combinación de Scrapemark (encontrar urls - py2 ) y httlib2 (descarga de imágenes - py2 + 3). El scrapemark.py tiene 500 líneas de código, pero usa expresiones regulares, por lo que puede que no sea tan rápido, no se probó.

Ejemplo para raspar su sitio 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] ))

Uso:

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

Resultado:

[{'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'}]
Nils Lindemann
fuente
1

Haz tu vida más fácil usando CSS Selectors

Sé que he llegado tarde a la fiesta, pero tengo una buena sugerencia para ti.

El uso BeautifulSoupya se ha sugerido. Preferiría usarlo CSS Selectorspara raspar datos dentro de 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 
Umair
fuente
1

Si pensamos en obtener el nombre de los elementos de cualquier categoría específica, entonces podemos hacerlo especificando el nombre de clase de esa categoría usando el selector 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)

Estos son los resultados de búsqueda parciales:

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
SIM
fuente
0

Aquí hay un rastreador web simple, utilicé BeautifulSoup y buscaremos todos los enlaces (anclas) cuyo nombre de clase es _3NFO0d. Utilicé Flipkar.com, es una tienda minorista en línea.

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()
Atul Chavan
fuente
0

Python tiene buenas opciones para raspar la web. El mejor con un marco es scrapy . Puede ser un poco complicado para los principiantes, así que aquí hay un poco de ayuda.
1. Instale Python por encima de 3.5 (los más bajos hasta 2.7 funcionarán).
2. Crear un entorno en conda (hice esto).
3. Instale scrapy en una ubicación y corra desde allí.
4. Scrapy shellle dará una interfaz interactiva para probar su código.
5. Scrapy startproject projectnamecreará un marco.
6. Scrapy genspider spidernamecreará una araña. Puedes crear tantas arañas como quieras. Al hacerlo, asegúrese de estar dentro del directorio del proyecto.


La más fácil es usar las solicitudes y la hermosa sopa . Antes de comenzar, dé una hora de tiempo para revisar la documentación y resolverá la mayoría de sus dudas. BS4 ofrece una amplia gama de analizadores que puede elegir. Use user-agenty sleeppara facilitar el raspado. BS4 devuelve un bs.tag, así que úsalo variable[0]. Si hay js ejecutándose, no podrá raspar usando solicitudes y bs4 directamente. Puede obtener el enlace de la API y luego analizar el JSON para obtener la información que necesita o probar selenium.

Chris D'mello
fuente