Suche…


Einführung

Web-Scraping ist ein automatisierter, programmatischer Prozess, durch den Daten ständig von Webseiten "abgeschabt" werden können. Web Scraping, auch als Screen Scraping oder Web Harvesting bekannt, kann sofortige Daten von jeder öffentlich zugänglichen Webseite bereitstellen. Auf einigen Websites ist das Scraping von Websites möglicherweise illegal.

Bemerkungen

Nützliche Python-Pakete für das Web-Scraping (alphabetische Reihenfolge)

Anfragen stellen und Daten sammeln

requests

Ein einfaches, aber leistungsfähiges Paket für HTTP-Anfragen.

requests-cache

Caching für requests ; Das Zwischenspeichern von Daten ist sehr nützlich. In der Entwicklung bedeutet dies, dass Sie vermeiden müssen, eine Website unnötig zu treffen. Wenn Sie eine echte Sammlung ausführen, bedeutet dies, dass wenn Ihr Scraper aus irgendeinem Grund abstürzt (möglicherweise haben Sie nicht mit ungewöhnlichen Inhalten auf der Website umgegangen ...? Vielleicht ist die Website ausgefallen ...?), Können Sie die Sammlung sehr schnell wiederholen von wo du aufgehört hast.

scrapy

Nützlich für das Erstellen von Webcrawlern, bei denen Sie etwas Stärkeres benötigen, als requests und Seiten zu durchlaufen.

selenium

Python-Bindungen für Selenium WebDriver zur Browser-Automatisierung. Mit requests an HTTP - Anfragen direkt ist oft einfacher , für das Abrufen von Webseiten zu machen. Dies ist jedoch ein nützliches Werkzeug, wenn es nicht möglich ist, das gewünschte Verhalten einer Website nur mit requests zu replizieren, insbesondere wenn JavaScript zum Rendern von Elementen auf einer Seite erforderlich ist.

HTML-Analyse

BeautifulSoup

Fragen Sie HTML- und XML-Dokumente mit einer Reihe verschiedener Parser ab (in Python integrierter HTML-Parser, html5lib , lxml oder lxml.html ).

lxml

Verarbeitet HTML und XML. Kann verwendet werden, um Inhalte aus HTML-Dokumenten über CSS-Selektoren und XPath abzufragen und auszuwählen.

Ein einfaches Beispiel für die Verwendung von Anforderungen und lxml zum Abwischen einiger Daten

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

Web-Scraping-Sitzung mit Anforderungen verwalten

Es ist eine gute Idee, eine Web-Scraping-Sitzung durchzuführen, um die Cookies und andere Parameter beizubehalten. Zusätzlich kann es zu einer Leistungssteigerung führen , da requests.Session die zugrunde liegende TCP - Verbindung zu einem Host wieder verwendet:

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)

Scraping mit dem Scrapy-Framework

Zuerst müssen Sie ein neues Scrapy-Projekt einrichten. Geben Sie ein Verzeichnis ein, in dem Sie Ihren Code speichern möchten, und führen Sie Folgendes aus:

scrapy startproject projectName

Zum Kratzen brauchen wir eine Spinne. Spider definieren, wie eine bestimmte Site abgestreift wird. Hier ist der Code für eine Spinne, die den Links zu den am häufigsten gestellten Fragen zu StackOverflow folgt und einige Daten von jeder Seite ( Quelle ) kratzt:

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

Speichern Sie Ihre Spider-Klassen im Verzeichnis projectName\spiders . In diesem Fall - projectName\spiders\stackoverflow_spider.py .

Jetzt kannst du deine Spinne benutzen. Versuchen Sie beispielsweise (im Verzeichnis des Projekts) auszuführen:

scrapy crawl stackoverflow

Ändern Sie den Scrapy-Benutzeragenten

Manchmal wird der standardmäßige Scrapy-Benutzeragent ( "Scrapy/VERSION (+http://scrapy.org)" ) vom Host blockiert. Um den Standardbenutzeragenten zu ändern, öffnen Sie die Datei settings.py , entfernen Sie das Kommentarzeichen und bearbeiten Sie die folgende Zeile in die gewünschte Zeile.

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

Zum Beispiel

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'

Kratzen mit 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

Kratzen mit Selenium WebDriver

Einige Websites mögen es nicht, abgeschabt zu werden. In diesen Fällen müssen Sie möglicherweise einen echten Benutzer simulieren, der mit einem Browser arbeitet. Selen startet und steuert einen Webbrowser.

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) 

Selen kann viel mehr. Es kann Browser-Cookies ändern, Formulare ausfüllen, Mausklicks simulieren, Screenshots von Webseiten erstellen und benutzerdefiniertes JavaScript ausführen.

Einfacher Download von Webinhalten mit urllib.request

Das Standardbibliotheksmodul urllib.request kann zum Herunterladen von Webinhalten verwendet werden:

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)

Ein ähnliches Modul ist auch in Python 2 verfügbar.

Kratzen mit Locken

Importe:

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

Wird heruntergeladen:

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 : stummer Download

-A : Benutzeragentenflag

Parsing:

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


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow