Ich war am 20.9. und 21. auf der PyCon 2016.
Ich habe dem Vortrag zugehört, als ich aus verschiedenen Gründen nach dem Thema Python 3 gesucht habe, aber Einführung in Web Crawler Made with Python Das in eingeführte "** Scrapy **" schien interessant zu sein und war nur mit Python3 kompatibel. Deshalb habe ich beschlossen, einen Crawler mit Python3 zu erstellen.
Klicken Sie hier für das Video des Vortrags
――Ich mag eher die Art zu berühren und zu verstehen als die Theorie, also sind es viele verschiedene Dinge. ――Weil es Analphabet ist, denke ich, dass es schwer zu verstehen sein wird. ―― Aus diesem Grund denke ich, dass es viele Dinge gibt, die Sie dazu bringen, es zu lesen, aber bitte verstehen Sie!
Dieses Mal habe ich den Namen des Ramen-Shops in der Nähe der Firma **, die Punktzahl ** und die ** Koordinaten ** aus dem ** Essensprotokoll ** mit Scrapy abgerufen, und es macht keinen Spaß, ihn einfach abzurufen, also auf Google Map Ich habe versucht, mit der Javascript-API auf einmal auf einer Karte zu zeichnen. (Es wurde bestätigt, dass das Crawlen in ** robots.txt ** des Essprotokolls für alle Fälle nicht verboten ist.)
Die Konfiguration ist einfach.
Der Fluss ist so ① Verwenden Sie Scrapy, um ** Geschäftsnamen **, ** Punktzahl **, ** Breiten- / Längengrad ** aus dem ** Lebensmittelprotokoll ** abzurufen. ② Speichern Sie die Geschäftsinformationen in einer Datei. ③ Greifen Sie über den Browser auf den Server zu. ④ django (+ djang-gmapi) liest die Geschäftsinformationen, bettet sie in die Jinja-Vorlage ein, sodass sie die Javascirpt-API aufruft, und gibt sie zurück. ⑤ Zeigen Sie Google Map mit Javascript an.
Es stellte sich heraus, dass es so etwas war! (Die Anzahl der Fälle wurde zur einfachen Anzeige auf 1/5 reduziert.) Markierungen sind rot, wenn die Punktzahl 3,5 oder mehr beträgt, weiß, wenn die Punktzahl 3,0 oder weniger beträgt, und gelb dazwischen.
Wie erwartet gibt es vor dem Bahnhof Ogikubo / Koenji viele Ramen-Läden mit Highscores ...!
Nur einen kurzen Spaziergang vom Bahnhof Nakano entfernt befindet sich ein Geschäft.
Ich krieche und kruche so.
Sie können den "Geschäftsnamen" und die "Punkte" aus der Liste mit 20 Elementen abrufen, jedoch nur den "Breiten- und Längengrad". Ich kann es nur aus den detaillierten Informationen jedes Shops erhalten, also werde ich es von dort erhalten. Nachdem ich 20 Fälle abgeschlossen habe, werde ich die nächsten 20 Fälle abrufen.
Das Erfassungsintervall entspricht in etwa dem manuellen (10 Sekunden). ** Gentleman krabbelt **. Die Struktur der URL des Lebensmittelprotokolls ist einfach. Wenn Sie also die Basis-URL (start_urls) ändern, Es scheint, dass das Crawlen und Mappen mit anderen Listen als Ramen, anderen Orten als Tokio und verschiedenen Mustern durchgeführt werden kann.
・ Ubuntu 16.04.1 ・ Python 3.5.2 ・ Scrapy 1.2.0 * Mit Pip installieren ・ Django 1.8 ・ Django-gmapi https://bitbucket.org/dbinit/django-gmapi/
Laut der Moderatorin, Frau Makahi, schien es besser, Ubuntu mit apt-get zu installieren. Kann Python 3 Scrapy noch von apt gelöscht werden? Es schien so, als hätte ich Scrapy mit Pip installiert. Im Moment kann ich es ohne Probleme bewegen.
Dies ist ein Auszug aus dem Spider-Teil, der das Herz des Krabbelns bildet. Ich habe Beutiful Soup zum Parsen verwendet.
tabelogcrawl/spiders/tlspider.py
# -*- coding: utf-8 -*-
from urllib.parse import urlparse, parse_qs
from datetime import datetime
import pytz
import scrapy
from scrapy.contrib.spiders import CrawlSpider
from bs4 import BeautifulSoup
from tabelogcrawl.items import TabelogcrawlItem
#Wie viele Artikel pro Seite?(Bei Überprüfung des Vorgangs auf 1 setzen)
LIMIT_GET_PER_PAGE = 20
class TLSpider(CrawlSpider):
name = "tlspider"
allowed_domains = ["tabelog.com"]
start_urls = (
'https://tabelog.com/tokyo/A1319/rstLst/ramen/1/?Srt=D&SrtT=rt&sort_mode=1',
)
def parse(self, response):
#Extrahieren Sie Geschäftsinformationen und Geschäftsergebnisse aus der Liste.
soup = BeautifulSoup(response.body, "html.parser")
summary_list = soup.find_all("a", class_="cpy-rst-name")
score_list = soup.find_all(
"span", class_="list-rst__rating-val", limit=LIMIT_GET_PER_PAGE)
for summary, score in zip(summary_list, score_list):
#Speichern Sie die erforderlichen Informationen für jedes Geschäft in TabelogcrawlItem.
jstnow = pytz.timezone(
'Asia/Tokyo').localize(datetime.now()).strftime('%Y/%m/%d')
item = TabelogcrawlItem()
item['date'] = jstnow
item['name'] = summary.string
item['score'] = score.string
href = summary["href"]
item['link'] = href
#Um den Breiten- und Längengrad des Geschäfts zu ermitteln
#Die Detailseite wird auch gecrawlt und in TabelogcrawlItem gespeichert.
request = scrapy.Request(
href, callback=self.parse_child)
request.meta["item"] = item
yield request
#Nächste Seite.
soup = BeautifulSoup(response.body, "html.parser")
next_page = soup.find(
'a', class_="page-move__target--next")
if next_page:
href = next_page.get('href')
yield scrapy.Request(href, callback=self.parse)
def parse_child(self, response):
#Extrahieren Sie den Breiten- und Längengrad des Geschäfts.
soup = BeautifulSoup(response.body, "html.parser")
g = soup.find("img", class_="js-map-lazyload")
longitude, latitude = parse_qs(
urlparse(g["data-original"]).query)["center"][0].split(",")
item = response.meta["item"]
item['longitude'] = longitude
item['latitude'] = latitude
return item
Für Django ist der Ansichtsteil ein Auszug. Der Teil, in dem die Farbe anhand der Punktzahl festgelegt wird, ist angemessen, daher möchte ich sie durch Normalisierung usw. etwas besser einfärben.
tabelogmap/gmapi/views.py
# -*- coding: utf-8 -*-
import codecs
import ast
from django import forms
from django.shortcuts import render_to_response
from gmapi import maps
from gmapi.forms.widgets import GoogleMap
SAVE_FILE = "../tabelog_data.txt"
class MapForm(forms.Form):
map = forms.Field(
widget=GoogleMap(
attrs={'width': 1850, 'height': 900}))
def index(request):
json_path = SAVE_FILE
raw_list = codecs.open(json_path, "r", encoding="utf-8").read().split("\n")
gmap = maps.Map(opts={
'center': maps.LatLng(35.70361991852944, 139.64842779766255),
'mapTypeId': maps.MapTypeId.ROADMAP,
'zoom': 15,
'mapTypeControlOptions': {
'style': maps.MapTypeControlStyle.DROPDOWN_MENU
},
})
info = maps.InfoWindow({
'content': 'Ramen Karte',
'disableAutoPan': True
})
for raw_data in raw_list:
try:
json_data = ast.literal_eval(raw_data)
except:
continue
if float(json_data["score"]) > 3.5:
color = "FF776B"
elif float(json_data["score"]) > 3.0:
color = "FFBB00"
else:
color = "FFFFFF"
marker_info = {
'map': gmap,
'position': maps.LatLng(
float(json_data["longitude"]),
float(json_data["latitude"])),
"label": "%s(%s)" % (
json_data["name"],
json_data["score"]),
"color": color
}
marker = maps.Marker(opts=marker_info)
maps.event.addListener(marker, 'mouseover', 'myobj.markerOver')
maps.event.addListener(marker, 'mouseout', 'myobj.markerOut')
info.open(gmap, marker)
context = {'form': MapForm(initial={'map': gmap})}
return render_to_response('index.html', context)
Scrapy ist einfach zu bedienen. Es fühlt sich so an, als ob es die Low-Layer-Verarbeitung auf gute Weise verbirgt. Es wird Spaß machen, wenn Sie die Planungsfunktion usw. auf gute Weise nutzen können. Es war so einfach, dass ich Python3 nicht lernen konnte, aber lol
Django-gmapi unterstützte Python3 nicht Ich habe es verschoben, während ich es mit 2to3 konvertiert habe, aber es hat etwas länger gedauert ... Ich weiß, dass Python3 nicht zu beängstigend ist, aber ich muss noch ein wenig lernen.
Recommended Posts