Hoe een Basic Web Crawler te bouwen om informatie van een website te trekken
Hebt u wel eens programmatuur specifieke informatie van een website willen vastleggen voor verdere verwerking? Zeg iets als sportuitslagen, beurstrends of de nieuwste rage, bitcoin en andere crypto-valutaprijzen? Als de informatie die u nodig hebt beschikbaar is op een website, kunt u een crawler (ook wel een scraper of een spin) schrijven om door de website te navigeren en precies datgene extraheren wat u nodig hebt. Laten we eens kijken hoe we dat in Python moeten doen.
Houd er rekening mee dat verschillende websites het gebruik van een crawler ontmoedigen om toegang te krijgen tot de informatie die de website biedt. Raadpleeg daarom de algemene voorwaarden van de website voordat u een crawler op een website implementeert.
Scrapy installeren
We gebruiken een python-module genaamd Scrapy voor het verwerken van het eigenlijke crawlen. Het is snel, eenvoudig en kan met een browser op meerdere webpagina's navigeren.
Merk echter op dat scrapy geen faciliteiten heeft om JavaScript te verwerken bij het navigeren op de website. Dus die websites en apps die javascript gebruiken om de gebruikersinterface te manipuleren, kunnen met deze benadering niet goed worden gecrawld.
Laten we nu scrapy installeren. We gebruiken virtualenv Leer hoe de Python virtuele omgeving te gebruiken Leer hoe de Python virtuele omgeving te gebruiken Of je nu een ervaren Python-ontwikkelaar bent, of je bent nog maar net begonnen, het leren van een virtuele omgeving is essentieel voor elk Python-project. Lees meer om scrapy te installeren. Dit stelt ons in staat om scrapy in een directory te installeren zonder andere op het systeem geïnstalleerde modules aan te tasten.
Maak een map en initialiseer een virtuele omgeving in die map.
mkdir crawler cd crawler virtualenv venv. venv / bin / activate
U kunt scrapy nu in deze map installeren.
pip installeer scrapy
Controleer of scrapy correct is geïnstalleerd.
scrapy # prints Scrapy 1.4.0 - geen actief project Gebruik: scrapy [options] [args] Beschikbare commando's: bench Snel referentietest uitvoeren Haal een URL op met de scrupy downloader-genspider Genereer een nieuwe spin met vooraf gedefinieerde sjablonen runspider Voer een onafhankelijke spin uit (zonder een project te maken) ...
Een website bouwen Crawler (ook wel een spin genoemd)
Laten we nu een crawler schrijven voor het laden van wat informatie. We beginnen met het schrapen van wat informatie van een Wikipedia-pagina op een batterij van https://en.wikipedia.org/wiki/Battery_(electricity).
De eerste stap bij het schrijven van een crawler is het definiëren van een python-klasse die zich uitstrekt van scrapy.Spider. Laten we deze klasse noemen Spider1.
Als een minimum vereist een spinklasse het volgende:
- een naam voor het identificeren van de spin, “Wikipedia” in dit geval.
- een start_urls variabele met een lijst met URL's waaruit u kunt gaan crawlen. We gebruiken de hierboven getoonde Wikipedia-URL voor onze eerste crawl.
- een ontleden () methode die - hoewel een no-op voor nu - wordt gebruikt om de webpagina te verwerken om te extraheren wat we willen.
import scrapy class spider1 (scrapy.Spider): name = 'Wikipedia' start_urls = ['https://en.wikipedia.org/wiki/Battery_(electricity)'] def parse (self, response): pass
We kunnen deze spin nu uitvoeren om te controleren of alles goed werkt. Het wordt als volgt uitgevoerd.
scrapy runspider spider1.py # prints 2017-11-23 09:09:21 [scrapy.utils.log] INFO: Scrapy 1.4.0 gestart (bot: scrapybot) 2017-11-23 09:09:21 [scrapy.utils .log] INFO: Overgeschreven instellingen: 'SPIDER_LOADER_WARN_ONLY': True 2017-11-23 09:09:21 [scrapy.middleware] INFO: Ingeschakelde extensies: ['scrapy.extensions.memusage.MemoryUsage', 'scrapy.extensions .logstats.LogStats', ...
Loggen uitschakelen
Zoals je ziet, genereert scrapy lopen met onze minimale klasse een reeks output die ons niet zo duidelijk is. Laten we het logging-niveau instellen op waarschuwing en probeer het opnieuw. Voeg de volgende regels toe aan het begin van het bestand.
import logging logging.getLogger ('scrapy'). setLevel (logging.WARNING)
Bij het opnieuw uitvoeren van de spider zouden we een minimum van de log-berichten moeten zien.
Chrome Inspector gebruiken
Het extraheren van informatie van een webpagina bestaat uit het bepalen van de positie van het HTML-element waarvan we informatie willen. Een leuke en eenvoudige manier om de positie van een element te vinden Zoek uit website-problemen met Chrome-ontwikkelaarstools Of Firebug bereken problemen met de website met Chrome-ontwikkelaarstools of Firebug Als je mijn jQuery-tutorials tot nu toe hebt gevolgd, ben je misschien al tegen het lijf gelopen sommige codeproblemen en niet bekend hoe ze te repareren. Wanneer u geconfronteerd wordt met een niet-functioneel stukje code, is het zeer ... Lees Meer van de Chrome Web Browser is om de Inspector te gebruiken.
- Navigeer naar de juiste pagina in Chrome.
- Plaats de muis op het element waarvoor u de informatie wilt.
- Klik met de rechtermuisknop om het contextmenu te openen.
- kiezen Inspecteren van het menu.
Dat zou de ontwikkelaarsconsole moeten openen met de Elements tabblad geselecteerd. Onder het tabblad ziet u de statusbalk met de positie van het element als volgt:
html body div # content.mw-body h1 # firstHeading.firstHeading.
Zoals we hieronder uitleggen, hebt u enkele of alle delen van deze positie nodig.
De titel extraheren
Laten we nu wat code toevoegen aan de ontleden () methode om de titel van de pagina te extraheren.
... def parse (self, response): print response.css ('h1 # firstHeading :: text'). Extract () ...
De antwoord argument voor de methode ondersteunt een methode genaamd css () die elementen uit de pagina selecteert met behulp van de gegeven locatie. Voor ons geval is het element h1.firstHeading. We hebben de tekstinhoud van het element nodig dus voegen we toe ::tekst naar de selectie. eindelijk, de extract() methode retourneert het geselecteerde element.
Bij het opnieuw uitvoeren van scrapy in deze klasse, krijgen we de volgende uitvoer:
[u'Batterij (elektriciteit) ']
Dit laat zien dat de titel is geëxtraheerd in een lijst met unicode-reeksen.
Hoe zit het met de beschrijving?
Om nog meer aspecten van het extraheren van gegevens van webpagina's te demonstreren, moeten we de eerste alinea van de beschrijving van de bovenstaande Wikipedia-pagina bekijken.
Bij inspectie met behulp van de Chrome-ontwikkelaarsconsole vinden we dat de locatie van het element is (de rechte hoeksteun (>) geeft een relatie tussen moeder en kind aan tussen de elementen):
div # mw-inhoud-text> div> p
Deze locatie komt terug allemaal de p overeenkomende elementen, inclusief de volledige beschrijving. Omdat we alleen de eerste willen p element, gebruiken we de volgende extractor:
response.css ( 'div # mw-inhoud-text> div> p') [0]
Om alleen de tekstinhoud te extraheren, voegen we CSS-extractor toe ::tekst:
response.css ( 'div # mw-inhoud-text> div> p') [0] .css ( ':: text')
De uiteindelijke expressie gebruikt extract() die een lijst met unicode-reeksen retourneert. We gebruiken de python join () functie om deel te nemen aan de lijst.
def parse (self, response): print ".join (response.css ('div # mw-content-text> div> p') [0] .css (':: text'). extract ())
De uitvoer van scrapy uitvoeren met deze klasse is wat we zoeken:
Een elektrische batterij is een apparaat dat bestaat uit een of meer elektrochemische cellen met externe aansluitingen voor elektrische apparaten zoals zaklantaarns, smartphones en elektrische auto's. [1] Wanneer een batterij stroom levert, is de positieve terminal ...
Gegevens verzamelen met opbrengst
De bovenstaande code print de geëxtraheerde gegevens naar de console. Wanneer u gegevens moet verzamelen als JSON, kunt u de opbrengst uitspraak. De weg opbrengst werkt als volgt - het uitvoeren van een functie die een bevat opbrengst statement retourneert wat de beller een generator noemt. De generator is een functie die de beller herhaaldelijk kan uitvoeren totdat deze wordt beëindigd.
Hier is dezelfde code als hierboven, maar die de opbrengst statement om de lijst met p elementen binnen de HTML.
... def parse (self, response): for e in response.css ('div # mw-content-text> div> p'): yield 'para': ". Join (e.css (':: text') ) .extract ()). strip () ...
U kunt nu de spider uitvoeren door een uitvoer JSON-bestand als volgt op te geven:
scrapy runspider spider3.py -o joe.json
De gegenereerde output is als volgt:
["para": "Een elektrische batterij is een apparaat dat bestaat uit een of meer elektrochemische cellen met externe aansluitingen voor elektrische apparaten zoals zaklantaarns, smartphones en elektrische auto's. [1] Wanneer een batterij stroom levert, is het van positieve terminal is de kathode en de negatieve pool is de anode. [2] De terminal die als negatief is gemarkeerd, is de bron van elektronen die, wanneer aangesloten op een extern circuit, stroomt en energie levert aan een extern apparaat. circuit, kunnen elektrolyten zich verplaatsen als ionen in, waardoor de chemische reacties kunnen worden voltooid op de afzonderlijke terminals en dus energie leveren aan het externe circuit. Het is de beweging van die ionen in de batterij waardoor stroom uit de batterij kan stromen om werk te verrichten. [3] Historisch gezien verwijst de term \ "batterij \" specifiek naar een apparaat dat is samengesteld uit meerdere cellen, maar het gebruik is verder geëvolueerd met apparaten die zijn samengesteld uit een zonde cel. [4] ", " para ":" Primaire (wegwerpbatterijen voor eenmalig gebruik of \ "wegwerpbatterijen \") worden eenmalig gebruikt en weggegooid; de elektrodematerialen worden onherroepelijk veranderd tijdens ontlading. Veel voorkomende voorbeelden zijn de alkalinebatterij die wordt gebruikt voor zaklampen en een groot aantal draagbare elektronische apparaten. Secundaire (oplaadbare) batterijen kunnen worden ontladen en meerdere keren worden opgeladen ...
Verwerking van meerdere stukjes informatie
Laten we nu kijken naar het extraheren van meerdere bits gerelateerd aan informatie. Voor dit voorbeeld extraheren we top IMDB Box Office-treffers voor het huidige weekend. Deze informatie is beschikbaar op http://www.imdb.com/chart/boxoffice, in een tabel met een rij met informatie voor elke hit.
We extraheren verschillende velden in elke rij met behulp van het volgende ontleden () methode. Wederom zijn de element-CSS-locaties bepaald met behulp van de Chrome-ontwikkelaarsconsole zoals hierboven uitgelegd:
... def parse (self, response): for e in response.css ('div # boxoffice> table> tbody> tr'): yield 'title': ". Join (e.css ('td.titleColumn> a: : text '). extract ()). strip (),' weekend ': ". join (e.css (' td.ratingColumn ') [0] .css (' :: text '). extract ()). strip (), 'gross': ". join (e.css ('td.ratingColumn') [1] .css ('span.secondaryInfo :: text'). extract ()). strip (), 'weken' : ". join (e.css ('td.weeksColumn :: text'). extract ()). strip (), 'image': e.css ('td.posterColumn img :: attr (src)'). extract_first (), ...
Merk op dat de beeld selector hierboven specificeert dat img is een afstammeling van td.posterColumn, en we extraheren het attribuut genaamd src de uitdrukking gebruiken :: attr (src).
Als de spin nu wordt uitgevoerd, wordt de volgende JSON geretourneerd:
["gross": "$ 93.8M", "weeks": "1", "weekend": "$ 93.8M", "image": "https://images-na.ssl-images-amazon.com/images /M/MV5BYWVhZjZkYTItOGIwYS00NmRkLWJlYjctMWM0ZjFmMDU4ZjEzXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UY67_CR0,0,45,67_AL_.jpg "," title ":" Justice League ", " gross ":" $ 27.5M "," weeks ":" 1 "," weekend ":" $ 27.5M "," image ":" https://images-na.ssl-images-amazon.com/images/M/MV5BYjFhOWY0OTgtNDkzMC00YWJkLTk1NGEtYWUxNjhmMmQ5ZjYyXkEyXkFqcGdeQXVyMjMxOTE0ODA@._V1_UX45_CR0,0,45,67_AL_.jpg "," title ":" Wonder " , "gross": "$ 247.3M", "weeks": "3", "weekend": "$ 21.7M", "image": "https://images-na.ssl-images-amazon.com/ images / M / MV5BMjMyNDkzMzI1OF5BMl5BanBnXkFtZTgwODcxODg5MjI @ ._ V1_UY67_CR0,0,45,67_AL_.jpg "," title ":" Thor: Ragnarok ", ...]
Uw crawler gebruiken
Laten we dit artikel nu afsluiten met enkele opvallende punten:
- Python gebruiken met scrapy maakt het gemakkelijk om website-crawlers te schrijven om alle informatie te extraheren die je nodig hebt.
- De Chrome-ontwikkelaarsconsole (of Firebug-tool van Firefox) helpt bij het vinden van elementlocaties om uit te pakken.
- Python's opbrengst verklaring helpt bij het extraheren van herhaalde gegevenselementen.
Heeft u specifieke projecten in gedachten voor het afschrapen van websites? En met welke problemen heb je geprobeerd om het op gang te krijgen? Laat het ons weten in de comments hieronder.
Image Credit: dxinerz / Depositphotos | Lulzmango / Wikimedia Commons
Meer informatie over: Programming, Python, Webmasterhulpprogramma's.