Wenn Sie das Wort "kratzen" sagen, gibt es ungefähr zwei Dinge: "kriechen" und "kratzen". Ich war verwirrt, also werde ich es einmal klären.
So werde ich zum Beispiel von der Seite der Shogi-Föderation den Titel meines Lieblingsschachmanns extrahieren. Toka ist eine Übersetzung von "Scraping".
scrapy
Lassen Sie es uns tatsächlich kratzen. Wenn ich darüber nachdenke, habe ich bisher nur PHP verwendet Ich habe mich bemüht, die gewünschten Informationen mit Goutte usw. von der Seite zu extrahieren.
Also habe ich erfahren, dass Python, das ich kürzlich eingeführt habe, eine Bibliothek (Framework?) Namens Scrapy hat, die das Scraping sehr einfach macht.
Dieses Mal werde ich dies verwenden, um Informationen über meine Lieblingsschachfiguren auf der Seite der Shogi-Föderation zu sammeln.
$ pip install scrapy
Komplett
Nun, ich bin ein super Anfänger, der Python überhaupt nicht versteht, also werde ich das Tutorial Schritt für Schritt ausprobieren, um ein Gefühl dafür zu bekommen.
In der Dokumentation gab es eine Tutorial-Ecke. https://docs.scrapy.org/en/latest/intro/tutorial.html
Es ist Englisch, aber es ist ganz so.
Ich möchte etwas in dieser Reihenfolge tun.
scrapy startproject tutorial
Das scheint gut zu sein.
[vagrant@localhost test]$ scrapy startproject tutorial
New Scrapy project 'tutorial', using template directory '/usr/lib64/python3.5/site-packages/scrapy/templates/project', created in:
/home/vagrant/test/tutorial
You can start your first spider with:
cd tutorial
scrapy genspider example example.com
[vagrant@localhost test]$ ll
Insgesamt 0
drwxr-xr-x 3 Vagabund Vagabund 38 April 16 04:15 tutorial
Ein Verzeichnis namens Tutorial wurde erstellt!
Es gibt also verschiedene Dinge, aber laut Dokument hat jede Datei die folgenden Rollen.
tutorial/
scrapy.cfg #Bereitstellungskonfigurationsdatei
tutorial/ # project's Python module, you'll import your code from here
__init__.py
items.py # project items definition file
pipelines.py # project pipelines file
settings.py # project settings file
spiders/ # a directory where you'll later put your spiders
__init__.py
Ich habe nichts anderes als die Bereitstellungskonfigurationsdatei verstanden lol
Erstellen Sie eine Datei mit dem Namen "quote_spider.py" unter "tutorial / spides /" und erstellen Sie sie, da etwas kopiert und eingefügt werden muss.
[vagrant@localhost tutorial]$ vi tutorial/spiders/quotes_spider.py
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)
scrapy crawl quotes
Es scheint, dass Sie damit gehen können.
Nachdem etwas herauskam, wurden "Quotes-1.html" und "Quotes-2.html" erstellt
[vagrant@localhost tutorial]$ ll
32 insgesamt
-rw-rw-r--1 Vagabund Vagabund 11053 16. April 04:27 quotes-1.html
-rw-rw-r--1 Vagabund Vagabund 13734 16. April 04:27 quotes-2.html
-rw-r--r--1 Vagabund Vagabund 260 16. April 04:15 scrapy.cfg
drwxr-xr-x 4 Vagabund Vagabund 129 16. April 04:15 tutorial
Ich schrieb hier "Lassen Sie uns die aus der Befehlszeile extrahierten Informationen ausgeben", Als ich mir den Inhalt der Analysemethode ansah, machte ich eigentlich nur so etwas wie ↓
quote-% s.html
anImmerhin gibt diese Methode am Ende nur das Objekt "Scrapy.Request" zurück, aber es scheint, dass dies durch einfaches Schreiben von "start_urls" realisiert werden kann.
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
Dies ist in Ordnung, ohne dass Sie sich die Mühe machen müssen, die Methode "start_requests" zu definieren
Das Tutorial sagt: "Um zu erfahren, wie sich Scrapy tatsächlich herauszieht, verwenden Sie die" Scrapy Shell "."
Ich werde es sofort versuchen
[vagrant@localhost tutorial]$ scrapy shell 'http://quotes.toscrape.com/page/1/'
...Unterlassung...
2017-04-16 04:36:51 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x7fbb13dd0080>
[s] item {}
[s] request <GET http://quotes.toscrape.com/page/1/>
[s] response <200 http://quotes.toscrape.com/page/1/>
[s] settings <scrapy.settings.Settings object at 0x7fbb129308d0>
[s] spider <DefaultSpider 'default' at 0x7fbb11f14828>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>> response.css('title')
[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]
Oh, es scheint, dass so etwas wie ein Titelelement extrahiert werden kann.
Diese reponse.css (xxx)
gibt eine XML mit dem Namen [SelectorList] zurück (https://docs.scrapy.org/en/latest/topics/selectors.html#scrapy.selector.SelectorList). Oder ein Objekt, das HTML umschließt.
Also werde ich mehr Daten von hier extrahieren. Das kann man auch sagen.
Extrahieren Sie den Text des Titels als Testversion.
>>> response.css('title::text').extract()
['Quotes to Scrape']
:: text
bedeutet, dass nur das Textelement aus diesem >>> response.css('title').extract()
['<title>Quotes to Scrape</title>']
Beim Extrahieren wird SelectorList zurückgegeben, sodass im Grunde der Listentyp zurückgegeben wird.
(Deshalb war alles oben von []
umgeben)
Wenn Sie eine bestimmte erhalten möchten, geben Sie die Listennummer an oder verwenden Sie "extract_first", um das erste Element abzurufen.
>>> response.css('title::text').extract_first()
'Quotes to Scrape'
>>> response.css('title::text')[0].extract()
'Quotes to Scrape'
##Es gibt nur einen Titel auf dieser Webseite. Wenn Sie also den zweiten angeben, werden Sie wütend
>>> response.css('title::text')[1].extract()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python3.5/site-packages/parsel/selector.py", line 58, in __getitem__
o = super(SelectorList, self).__getitem__(pos)
IndexError: list index out of range
Was ist xpath? Ich dachte, aber @ merrills Artikel war sehr leicht zu verstehen.
http://qiita.com/merrill/items/aa612e6e865c1701f43b
Es scheint, dass Sie so etwas wie atag im vierten td im `tbody aus dem HTML angeben können.
Wenn ich es in diesem Beispiel sofort verwende, sieht es so aus
>>> response.xpath('//title')
[<Selector xpath='//title' data='<title>Quotes to Scrape</title>'>]
>>> response.xpath('//title/text()').extract_first()
'Quotes to Scrape'
Lassen Sie uns den Textteil und den Autor von http://quotes.toscrape.com/page/1/ extrahieren, der jetzt das Ziel des Scrapings ist.
Setzen Sie zuerst das erste div in eine Variable namens quote
>>> quote = response.css("div.quote")[0]
>>> title = quote.css("span.text::text").extract_first()
>>> title
'“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'
Es ist gelungen, den Textteil zu extrahieren
>>> autor = quote.css("small.author::text").extract_first()
>>> autor
'Albert Einstein'
Es ist wahnsinnig einfach.
>>> tags = quote.css("div.tags a.tag::text").extract()
>>> tags
['change', 'deep-thoughts', 'thinking', 'world']
Ich kann es richtig mit Listentyp extrahieren
>>> for quote in response.css("div.quote"):
>>> text = quote.css("span.text::text").extract_first()
>>> author = quote.css("small.author::text").extract_first()
>>> tags = quote.css("div.tags a.tag::text").extract()
>>> print(dict(text=text, author=author, tags=tags))
{'tags': ['change', 'deep-thoughts', 'thinking', 'world'], 'author': 'Albert Einstein', 'text': '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'}
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
def parse(self, response):
for quote in response.css("div.quote"):
yield {
'text' : quote.css('span.text::text').extract_first(),
'author' : quote.css('small.author::text').extract_first(),
'tags' : quote.css('div.tags a.tag::text').extract()
}
Ich werde es so umschreiben und ausführen.
[vagrant@localhost tutorial]$ scrapy crawl quotes
2017-04-16 05:27:09 [scrapy.utils.log] INFO: Scrapy 1.3.3 started (bot: tutorial)
2017-04-16 05:27:09 [scrapy.utils.log] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'tutorial.spiders', 'BOT_NAME': 'tutorial', 'SPIDER_MODULES': ['tutorial.spiders'], 'ROBOTSTXT_OBEY': True}
...Unterlassung...
{'author': 'Albert Einstein', 'text': '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”', 'tags': ['change', 'deep-thoughts', 'thinking', 'world']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'J.K. Rowling', 'text': '“It is our choices, Harry, that show what we truly are, far more than our abilities.”', 'tags': ['abilities', 'choices']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'Albert Einstein', 'text': '“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”', 'tags': ['inspirational', 'life', 'live', 'miracle', 'miracles']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'Jane Austen', 'text': '“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”', 'tags': ['aliteracy', 'books', 'classic', 'humor']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'Marilyn Monroe', 'text': "“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”", 'tags': ['be-yourself', 'inspirational']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'Albert Einstein', 'text': '“Try not to become a man of success. Rather become a man of value.”', 'tags': ['adulthood', 'success', 'value']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{'author': 'André Gide', 'text': '“It is better to be hated for what you are than to be loved for what you are not.”', 'tags': ['life', 'love']}
2017-04-16 05:27:11 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
...Unterlassung...
Es gibt verschiedene Dinge, aber es scheint, dass sie extrahiert werden können.
** Legen Sie es in eine Datei und sehen Sie es **
[vagrant@localhost tutorial]$ scrapy crawl quotes -o result.json
Mal sehen, das Ergebnis
[vagrant@localhost tutorial]$ cat result.json
[
{"tags": ["change", "deep-thoughts", "thinking", "world"], "text": "\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d", "author": "Albert Einstein"},
{"tags": ["abilities", "choices"], "text": "\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d", "author": "J.K. Rowling"},
{"tags": ["inspirational", "life", "live", "miracle", "miracles"], "text": "\u201cThere are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.\u201d", "author": "Albert Einstein"},
{"tags": ["aliteracy", "books", "classic", "humor"], "text": "\u201cThe person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.\u201d", "author": "Jane Austen"},
{"tags": ["be-yourself", "inspirational"], "text": "\u201cImperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.\u201d", "author": "Marilyn Monroe"},
{"tags": ["adulthood", "success", "value"], "text": "\u201cTry not to become a man of success. Rather become a man of value.\u201d", "author": "Albert Einstein"},
{"tags": ["life", "love"], "text": "\u201cIt is better to be hated for what you are than to be loved for what you are not.\u201d", "author": "Andr\u00e9 Gide"},
{"tags": ["edison", "failure", "inspirational", "paraphrased"], "text": "\u201cI have not failed. I've just found 10,000 ways that won't work.\u201d", "author": "Thomas A. Edison"},
{"tags": ["misattributed-eleanor-roosevelt"], "text": "\u201cA woman is like a tea bag; you never know how strong it is until it's in hot water.\u201d", "author": "Eleanor Roosevelt"},
{"tags": ["humor", "obvious", "simile"], "text": "\u201cA day without sunshine is like, you know, night.\u201d", "author": "Steve Martin"},
{"tags": ["friends", "heartbreak", "inspirational", "life", "love", "sisters"], "text": "\u201cThis life is what you make it. No matter what, you're going to mess up sometimes, it's a universal truth. But the good part is you get to decide how you're going to mess it up. Girls will be your friends - they'll act like it anyway. But just remember, some come, some go. The ones that stay with you through everything - they're your true best friends. Don't let go of them. Also remember, sisters make the best friends in the world. As for lovers, well, they'll come and go too. And baby, I hate to say it, most of them - actually pretty much all of them are going to break your heart, but you can't give up because if you give up, you'll never find your soulmate. You'll never find that half who makes you whole and that goes for everything. Just because you fail once, doesn't mean you're gonna fail at everything. Keep trying, hold on, and always, always, always believe in yourself, because if you don't, then who will, sweetie? So keep your head high, keep your chin up, and most importantly, keep smiling, because life's a beautiful thing and there's so much to smile about.\u201d", "author": "Marilyn Monroe"},
{"tags": ["courage", "friends"], "text": "\u201cIt takes a great deal of bravery to stand up to our enemies, but just as much to stand up to our friends.\u201d", "author": "J.K. Rowling"},
{"tags": ["simplicity", "understand"], "text": "\u201cIf you can't explain it to a six year old, you don't understand it yourself.\u201d", "author": "Albert Einstein"},
{"tags": ["love"], "text": "\u201cYou may not be her first, her last, or her only. She loved before she may love again. But if she loves you now, what else matters? She's not perfect\u2014you aren't either, and the two of you may never be perfect together but if she can make you laugh, cause you to think twice, and admit to being human and making mistakes, hold onto her and give her the most you can. She may not be thinking about you every second of the day, but she will give you a part of her that she knows you can break\u2014her heart. So don't hurt her, don't change her, don't analyze and don't expect more than she can give. Smile when she makes you happy, let her know when she makes you mad, and miss her when she's not there.\u201d", "author": "Bob Marley"},
{"tags": ["fantasy"], "text": "\u201cI like nonsense, it wakes up the brain cells. Fantasy is a necessary ingredient in living.\u201d", "author": "Dr. Seuss"},
{"tags": ["life", "navigation"], "text": "\u201cI may not have gone where I intended to go, but I think I have ended up where I needed to be.\u201d", "author": "Douglas Adams"},
{"tags": ["activism", "apathy", "hate", "indifference", "inspirational", "love", "opposite", "philosophy"], "text": "\u201cThe opposite of love is not hate, it's indifference. The opposite of art is not ugliness, it's indifference. The opposite of faith is not heresy, it's indifference. And the opposite of life is not death, it's indifference.\u201d", "author": "Elie Wiesel"},
{"tags": ["friendship", "lack-of-friendship", "lack-of-love", "love", "marriage", "unhappy-marriage"], "text": "\u201cIt is not a lack of love, but a lack of friendship that makes unhappy marriages.\u201d", "author": "Friedrich Nietzsche"},
{"tags": ["books", "contentment", "friends", "friendship", "life"], "text": "\u201cGood friends, good books, and a sleepy conscience: this is the ideal life.\u201d", "author": "Mark Twain"},
{"tags": ["fate", "life", "misattributed-john-lennon", "planning", "plans"], "text": "\u201cLife is what happens to us while we are making other plans.\u201d", "author": "Allen Saunders"}
Poi Poi! !! !! !! Sehr einfach ww
Übrigens habe ich jetzt alle Übergangsziel-URLs direkt in start_urls aufgelistet. Wie üblich möchten Sie jedoch möglicherweise einem bestimmten Link auf der Seite folgen, um die gewünschten Daten rekursiv abzurufen.
In einem solchen Fall scheint es gut, die URL des Links abzurufen und Ihre eigene Analyse aufzurufen.
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback=self.parse)
Ich fühle mich so. Wenn es "next_page" gibt, fühlt es sich an, als würde man wieder herumgehen.
Ich frage mich, ob urljoin
es zu einer netten Patrouillen-URL macht.
Hier befindet sich ein Link im Autorenteil von http://quotes.toscrape.com, sodass ein Tutorial eingeführt wird, um weitere Informationen zu erhalten.
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/',
]
def parse(self, response):
#Holen Sie sich einen Link zur Detailseite des Autors
for href in response.css('.author + a::attr(href)').extract():
yield scrapy.Request(response.urljoin(href), callback=self.parse_author)
#Holen Sie sich Pagenation Link
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not NONE:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback=self.parse)
def parse_author(self, response):
#Auszug aus der Antwort in der empfangenen Abfrage und Streifen(Trimmartiges Ding)Machen
def extract_with_css(query):
return response.css(query).extract_first().strip()
yield {
'name' : extract_with_css('h3.author-title::text'),
'birthdate' : extract_with_css('.author-born-date::text'),
'bio': extract_with_css('.author-description::text'),
}
Wenn du es so machst
―― 1. Folgen Sie dem Link des Autors und führen Sie parse_author
aus (extrahieren Sie den Namen, das Geburtsdatum und die Beschreibung).
―― 2. Wenn Paging vorhanden ist, analysieren Sie es erneut für die nächste Seite
―― 3. Wiederholen Sie diesen Vorgang, bis kein Paging mehr erfolgt
Es ist möglich, so etwas in nur ein paar Dutzend Zeilen zu schreiben ...
Ich wusste nicht, wie ich das benutzen sollte, also habe ich es bestanden.
--Erstellen Sie ein Projekt mit Scrapy
Wenn ich mit -o
an json ausgebe, ist die Zeichenkette nicht codiert und kann nicht gelesen werden.
Dies kann gelöst werden, indem eine Zeile von "FEED_EXPORT_ENCODING =" utf-8 "zu" [Projektname] / settings.py "hinzugefügt wird.
Ich habe etwas gemacht, das die Daten des Schwertkämpfers kratzt.
Was ich getan habe
Der eigentliche Code sieht so aus (es ist einfach w)
import scrapy
class QuotesSpider(scrapy.Spider):
name = "kisi"
start_urls = [
'https://www.shogi.or.jp/player/',
]
def parse(self, response):
#Holen Sie sich einen Link zur Detailseite des Schwertkämpfers
for href in response.css("p.ttl a::attr(href)").extract():
yield scrapy.Request(response.urljoin(href), callback=self.parse_kisi)
def parse_kisi(self, response):
def extract_with_xpath(query):
return response.xpath(query).extract_first().strip()
yield {
'name' : extract_with_xpath('//*[@id="contents"]/div[2]/div/div[2]/div/div/h1/span[1]/text()'),
'birth' : extract_with_xpath('//*[@id="contents"]/div[2]/div/div[2]/table/tbody/tr[2]/td/text()'),
'sisho' : extract_with_xpath('//*[@id="contents"]/div[2]/div/div[2]/table/tbody/tr[4]/td/text()'),
}
[vagrant@localhost tutorial]$ head kisi.json
[
{"name": "Akira Watanabe", "birth": "23. April 1984(32 Jahre alt)", "sisho": "Kazuharu Toshiji 7. Dan"},
{"name": "Masahiko Urano", "birth": "14. März 1964(53 Jahre alt)", "sisho": "(Spät) Nakai Ryukichi 8. Dan"},
{"name": "Masaki Izumi", "birth": "11. Januar 1961(56 Jahre alt)", "sisho": "Sekine Shigeru 9. Dan"},
{"name": "Koji Tosa", "birth": "30. März 1955(62 Jahre alt)", "sisho": "(Spät) Shizuo Kiyono 8. Dan"},
{"name": "Hiroshi Kamiya", "birth": "21. April 1961(55 Jahre alt)", "sisho": "(spät)Hisao Hirotsu 9. Dan"},
{"name": "Kensuke Kitahama", "birth": "28. Dezember 1975(41 Jahre alt)", "sisho": "Masayu Saeki 9. Dan"},
{"name": "Akutsu Hauptsteuer", "birth": "24. Juni 1982(34 Jahre alt)", "sisho": "Seiichiro Taki 8. Dan"},
{"name": "Takayuki Yamazaki", "birth": "14. Februar 1981(36 Jahre alt)", "sisho": "Nobuo Mori 7. Dan"},
{"name": "Akihito Hirose", "birth": "18. Januar 1987(30 Jahre alt)", "sisho": "Katsuura Shu 9. Dan"},
Sie können sehen, dass jeder es richtig bekommt. Es ist wirklich einfach.
--Starten von einer bestimmten Seite
Ich werde wenn möglich einen Artikel schreiben. (Nun, ich verstehe die Ausbeute nicht gut, ich kann nicht debuggen und ich muss Python studieren.)
Recommended Posts