Buscar..


Introducción

El raspado web es un proceso automatizado y programático a través del cual los datos se pueden " raspar " constantemente de las páginas web. También conocido como raspado de pantalla o recolección web, el raspado web puede proporcionar datos instantáneos desde cualquier página web de acceso público. En algunos sitios web, el raspado web puede ser ilegal.

Observaciones

Paquetes de Python útiles para raspado web (orden alfabético)

Realización de solicitudes y recogida de datos.

requests

Un paquete simple, pero poderoso para hacer peticiones HTTP.

requests-cache

Caché para requests ; almacenar datos en caché es muy útil. En desarrollo, significa que puede evitar golpear un sitio innecesariamente. Mientras ejecuta una colección real, significa que si su raspador se bloquea por algún motivo (tal vez no haya manejado algún contenido inusual en el sitio ... ¿Tal vez el sitio se haya caído ...?) Puede repetir la colección muy rápidamente de donde lo dejaste.

scrapy

Útil para crear rastreadores web, donde necesita algo más potente que usar requests e iterar a través de páginas.

selenium

Enlaces Python para Selenium WebDriver, para la automatización del navegador. El uso de requests para realizar solicitudes HTTP directamente es a menudo más sencillo para recuperar páginas web. Sin embargo, esto sigue siendo una herramienta útil cuando no es posible replicar el comportamiento deseado de un sitio usando solo las requests , particularmente cuando se requiere JavaScript para representar elementos en una página.

Análisis de HTML

BeautifulSoup

Consulte documentos HTML y XML, utilizando varios analizadores diferentes (el analizador HTML incorporado de Python, html5lib , lxml o lxml.html )

lxml

Procesos HTML y XML. Puede usarse para consultar y seleccionar contenido de documentos HTML a través de selectores de CSS y XPath.

Ejemplo básico de uso de solicitudes y lxml para raspar algunos datos

# For Python 2 compatibility.
from __future__ import print_function

import lxml.html
import requests


def main():
    r = requests.get("https://httpbin.org")
    html_source = r.text
    root_element = lxml.html.fromstring(html_source)
    # Note root_element.xpath() gives a *list* of results.
    # XPath specifies a path to the element we want.
    page_title = root_element.xpath('/html/head/title/text()')[0]
    print(page_title)

if __name__ == '__main__':
    main()

Mantenimiento de sesión web-scraping con peticiones.

Es una buena idea mantener una sesión de raspado web para conservar las cookies y otros parámetros. Además, puede dar lugar a una mejora del rendimiento porque requests.Session reutiliza la conexión TCP subyacente a un host:

import requests

with requests.Session() as session:
    # all requests through session now have User-Agent header set
    session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}

    # set cookies
    session.get('http://httpbin.org/cookies/set?key=value')

    # get cookies
    response = session.get('http://httpbin.org/cookies')
    print(response.text)

Raspado utilizando el marco de Scrapy

Primero tienes que configurar un nuevo proyecto Scrapy. Ingrese un directorio donde le gustaría almacenar su código y ejecute:

scrapy startproject projectName

Para raspar necesitamos una araña. Las arañas definen cómo se raspará un determinado sitio. Aquí está el código para una araña que sigue los enlaces a las preguntas más votadas en StackOverflow y raspa algunos datos de cada página ( fuente ):

import scrapy

class StackOverflowSpider(scrapy.Spider):
    name = 'stackoverflow'  # each spider has a unique name
    start_urls = ['http://stackoverflow.com/questions?sort=votes']  # the parsing starts from a specific set of urls

    def parse(self, response):  # for each request this generator yields, its response is sent to parse_question
        for href in response.css('.question-summary h3 a::attr(href)'):  # do some scraping stuff using css selectors to find question urls 
            full_url = response.urljoin(href.extract())
            yield scrapy.Request(full_url, callback=self.parse_question)

    def parse_question(self, response): 
        yield {
            'title': response.css('h1 a::text').extract_first(),
            'votes': response.css('.question .vote-count-post::text').extract_first(),
            'body': response.css('.question .post-text').extract_first(),
            'tags': response.css('.question .post-tag::text').extract(),
            'link': response.url,
        }

Guarda tus clases de arañas en el directorio nombre de projectName\spiders . En este caso, projectName\spiders\stackoverflow_spider.py .

Ahora puedes usar tu araña. Por ejemplo, intente ejecutar (en el directorio del proyecto):

scrapy crawl stackoverflow

Modificar agente de usuario de Scrapy

En ocasiones, el host bloquea el agente de usuario de Scrapy predeterminado ( "Scrapy/VERSION (+http://scrapy.org)" ). Para cambiar el agente de usuario predeterminado, abra settings.py , elimine el comentario y edite la siguiente línea como desee.

#USER_AGENT = 'projectName (+http://www.yourdomain.com)'

Por ejemplo

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'

Raspado utilizando BeautifulSoup4

from bs4 import BeautifulSoup
import requests

# Use the requests module to obtain a page
res = requests.get('https://www.codechef.com/problems/easy')

# Create a BeautifulSoup object
page = BeautifulSoup(res.text, 'lxml')   # the text field contains the source of the page

# Now use a CSS selector in order to get the table containing the list of problems
datatable_tags = page.select('table.dataTable')  # The problems are in the <table> tag,
                                                 # with class "dataTable"
# We extract the first tag from the list, since that's what we desire
datatable = datatable_tags[0]
# Now since we want problem names, they are contained in <b> tags, which are
# directly nested under <a> tags
prob_tags = datatable.select('a > b')
prob_names = [tag.getText().strip() for tag in prob_tags]

print prob_names

Raspado utilizando Selenium WebDriver

Algunos sitios web no les gusta ser raspado. En estos casos, es posible que necesite simular a un usuario real que trabaja con un navegador. Selenium lanza y controla un navegador web.

from selenium import webdriver

browser = webdriver.Firefox()  # launch firefox browser

browser.get('http://stackoverflow.com/questions?sort=votes')  # load url

title = browser.find_element_by_css_selector('h1').text  # page title (first h1 element)

questions = browser.find_elements_by_css_selector('.question-summary')  # question list

for question in questions:  # iterate over questions
    question_title = question.find_element_by_css_selector('.summary h3 a').text
    question_excerpt = question.find_element_by_css_selector('.summary .excerpt').text
    question_vote = question.find_element_by_css_selector('.stats .vote .votes .vote-count-post').text
    
    print "%s\n%s\n%s votes\n-----------\n" % (question_title, question_excerpt, question_vote) 

El selenio puede hacer mucho más. Puede modificar las cookies del navegador, rellenar formularios, simular clics del ratón, tomar capturas de pantalla de páginas web y ejecutar JavaScript personalizado.

Descarga de contenido web simple con urllib.request

El módulo de biblioteca estándar urllib.request se puede usar para descargar contenido web:

from urllib.request import urlopen

response = urlopen('http://stackoverflow.com/questions?sort=votes')    
data = response.read()

# The received bytes should usually be decoded according the response's character set
encoding = response.info().get_content_charset()
html = data.decode(encoding)

Un módulo similar también está disponible en Python 2 .

Raspado con rizo

importaciones:

from subprocess import Popen, PIPE
from lxml import etree
from io import StringIO

Descargando:

user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'
url = 'http://stackoverflow.com'
get = Popen(['curl', '-s', '-A', user_agent, url], stdout=PIPE)
result = get.stdout.read().decode('utf8')

-s : descarga silenciosa

-A : bandera de agente de usuario

Análisis:

tree = etree.parse(StringIO(result), etree.HTMLParser())
divs = tree.xpath('//div')


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow