Sök…


Introduktion

Webskrapning är en automatiserad, programmatisk process genom vilken data ständigt kan "skrapas" från webbsidor. Även känd som skärmskrapning eller skörd på webben, kan webbskrapning tillhandahålla omedelbar data från alla offentligt tillgängliga webbsidor. På vissa webbplatser kan webbskrotning vara olagligt.

Anmärkningar

Användbara Python-paket för webbskrapning (alfabetisk ordning)

Skicka förfrågningar och samla in data

requests

Ett enkelt, men kraftfullt paket för att göra HTTP-förfrågningar.

requests-cache

Cache för requests ; cachedata är mycket användbart. Under utveckling betyder det att du kan undvika att träffa en webbplats onödigt. När du kör en riktig samling betyder det att om din skrapa kraschar av någon anledning (kanske du inte hanterade något ovanligt innehåll på webbplatsen ...? Kanske sajten gick ned ...?) Kan du upprepa samlingen mycket snabbt där du slutade.

scrapy

Användbart för att bygga webbsökare, där du behöver något kraftfullare än att använda requests och iterera igenom sidor.

selenium

Pythonbindningar för Selenium WebDriver, för webbläsarautomation. Att använda requests att göra HTTP-förfrågningar direkt är ofta enklare för att hämta webbsidor. Detta förblir emellertid ett användbart verktyg när det inte går att replikera det önskade beteendet på en webbplats med enbart requests , särskilt när JavaScript krävs för att återge element på en sida.

HTML-parsning

BeautifulSoup

Fråga HTML- och XML-dokument med hjälp av ett antal olika parsers (Pythons inbyggda HTML Parser, html5lib , lxml eller lxml.html )

lxml

Bearbetar HTML och XML. Kan användas för att fråga och välja innehåll från HTML-dokument via CSS-väljare och XPath.

Grundläggande exempel på att använda förfrågningar och lxml för att skrapa lite data

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

Underhålla webbskrapningssession med förfrågningar

Det är en bra idé att hålla en webbskrapningssession för att kvarstå cookies och andra parametrar. Dessutom kan det resultera i en prestandaförbättring eftersom requests.Session återanvänder den underliggande TCP-anslutningen till en värd:

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)

Skrapning med Scrapy-ramverket

Först måste du ställa in ett nytt Scrapy-projekt. Ange en katalog där du vill lagra din kod och köra:

scrapy startproject projectName

För att skrapa behöver vi en spindel. Spindlar definierar hur en viss webbplats ska skrapas. Här är koden för en spindel som följer länkarna till de toppröstade frågorna om StackOverflow och skrapar lite data från varje sida ( källa ):

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

Spara dina spindelklasser i projectName\spiders . I detta fall - projectName\spiders\stackoverflow_spider.py .

Nu kan du använda din spindel. Prova till exempel att köra (i projektets katalog):

scrapy crawl stackoverflow

Ändra Scrapy användaragent

Ibland blockeras standard Scrapy-användaragenten ( "Scrapy/VERSION (+http://scrapy.org)" av värden. För att ändra standardanvändaragentens öppna settings.py , avmarkera och redigera följande rad till vad du än vill.

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

Till exempel

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'

Skrapa med hjälp av 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

Skrapning med Selenium WebDriver

Vissa webbplatser gillar inte att skrotas. I dessa fall kan du behöva simulera en riktig användare som arbetar med en webbläsare. Selenium lanserar och kontrollerar en webbläsare.

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 kan göra mycket mer. Det kan modifiera webbläsarens cookies, fylla i formulär, simulera musklick, ta skärmdumpar av webbsidor och köra anpassad JavaScript.

Enkel nedladdning av webbinnehåll med urllib.request

Standardbiblioteksmodulen urllib.request kan användas för att ladda ner webbinnehåll:

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)

En liknande modul finns också i Python 2 .

Skrapa med lock

import:

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

Laddar ner:

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 : tyst nedladdning

-A : flaggan för användaragent

analysera:

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow