Recherche…


Introduction

Le Web scraping est un processus automatisé et programmé grâce auquel les données peuvent être constamment «grattées» sur les pages Web. Également connu sous le nom de récupération d'écran ou de collecte Web, le balayage Web peut fournir des données instantanées à partir de n'importe quelle page Web accessible au public. Sur certains sites Web, le raclage Web peut être illégal.

Remarques

Paquets Python utiles pour le web scraping (ordre alphabétique)

Faire des demandes et collecter des données

requests

Un package simple mais puissant pour faire des requêtes HTTP.

requests-cache

Mise en cache pour les requests ; la mise en cache des données est très utile. En développement, cela signifie que vous pouvez éviter de frapper un site inutilement. Lorsque vous exécutez une collection réelle, cela signifie que si votre racloir plante pour une raison quelconque (vous n'avez peut-être pas manipulé de contenu inhabituel sur le site ...? Peut-être que le site est tombé ...?) D'où tu t'es arrêté.

scrapy

Utile pour créer des robots d'indexation sur le Web, où vous avez besoin de quelque chose de plus puissant que l'utilisation de requests et l'itération de pages.

selenium

Liaisons Python pour Selenium WebDriver, pour l'automatisation des navigateurs. L'utilisation de requests pour effectuer directement des requêtes HTTP est souvent plus simple pour récupérer des pages Web. Cependant, cela reste un outil utile lorsqu'il n'est pas possible de reproduire le comportement souhaité d'un site à l'aide de requests uniquement, en particulier lorsque JavaScript est requis pour rendre des éléments sur une page.

Analyse HTML

BeautifulSoup

Requête de documents HTML et XML à l'aide de plusieurs analyseurs (analyseur HTML intégré à Python, html5lib , lxml ou lxml.html )

lxml

Traite HTML et XML. Peut être utilisé pour interroger et sélectionner du contenu à partir de documents HTML via des sélecteurs CSS et XPath.

Exemple de base d'utilisation de requêtes et de lxml pour récupérer des données

# 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()

Maintenir la session Web-scraping avec les requêtes

Il est recommandé de conserver une session Web pour conserver les cookies et autres paramètres. En outre, cela peut entraîner une amélioration des performances, car requests.Session réutilise la connexion TCP sous-jacente à un hôte:

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)

Gratter en utilisant le cadre Scrapy

Vous devez d'abord créer un nouveau projet Scrapy. Entrez un répertoire dans lequel vous souhaitez stocker votre code et exécutez:

scrapy startproject projectName

Pour gratter, nous avons besoin d'une araignée. Les araignées définissent la manière dont un site donné sera raclé. Voici le code d'une araignée qui suit les liens vers les questions les plus votées sur StackOverflow et raconte certaines données de chaque page ( source ):

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,
        }

Enregistrez vos classes d'araignées dans le répertoire projectName\spiders . Dans ce cas - nom du projectName\spiders\stackoverflow_spider.py .

Vous pouvez maintenant utiliser votre araignée. Par exemple, essayez de courir (dans le répertoire du projet):

scrapy crawl stackoverflow

Modifier l'agent utilisateur Scrapy

Parfois, l'agent utilisateur Scrapy par défaut ( "Scrapy/VERSION (+http://scrapy.org)" ) est bloqué par l'hôte. Pour modifier l'agent utilisateur par défaut, ouvrez settings.py , décommentez et modifiez la ligne suivante selon vos souhaits.

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

Par exemple

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'

Gratter à l'aide de 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

Scraping utilisant Selenium WebDriver

Certains sites Web n'aiment pas être effacés. Dans ces cas, vous devrez peut-être simuler un utilisateur réel travaillant avec un navigateur. Selenium lance et contrôle un navigateur 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) 

Le sélénium peut faire beaucoup plus. Il peut modifier les cookies du navigateur, remplir des formulaires, simuler des clics de souris, réaliser des captures d'écran de pages Web et exécuter du code JavaScript personnalisé.

Téléchargement de contenu Web simple avec urllib.request

Le module de bibliothèque standard urllib.request peut être utilisé pour télécharger du contenu 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 module similaire est également disponible dans Python 2 .

Grattage avec boucle

importations:

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

Téléchargement:

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 : téléchargement silencieux

-A : drapeau de l'agent utilisateur

Analyse:

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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow