Um 2020 änderten sich die Spezifikationen der i-town-Seite, sodass ich ein entsprechendes Skript erstellte. Das folgende Skript wird erstellt
Geben Sie Schlüsselwörter und Bereiche ein und suchen Sie auf der i-town-Seite → Rufen Sie den Namen und die Adresse des Geschäfts aus den Suchergebnissen ab und geben Sie sie im CSV-Format aus
--Akte, die einen großen Einfluss auf den Service von i-town page haben
Das in diesem Artikel vorgestellte Programm führt keinen kontinuierlichen Zugriff mit einer Geschwindigkeit durch, die die normalerweise von Benutzern verwendete Geschwindigkeit bei weitem überschreitet, sodass es nicht unter die verbotenen Elemente fällt (wie es scheint).
Da das Kopieren zur Verwendung in einer Umgebung, die von Dritten angezeigt werden kann, verboten ist, Das Bild der Website usw. wird zum Zeitpunkt der Erläuterung nicht veröffentlicht
Die Website wird um 2020 aktualisiert. Wenn Sie in den Suchergebnissen nach unten scrollen, wird eine Schaltfläche mit dem Namen ** Mehr anzeigen ** angezeigt. Sie können nicht mehr alle Suchergebnisse abrufen (maximale Anzeige 1000), wenn Sie dies nicht mehrmals drücken.
Vorerst werde ich eine grobe Erklärung und das gesamte Programm veröffentlichen. (Detaillierte Erklärung wird später beschrieben)
Erstellen Sie eine Eingabeschnittstelle mit PysimpleGUI (es spielt keine Rolle, ob Sie sie nicht haben) Starten Sie Chrome (oder Firefox) mit dem Web-Treiber von Selen, zeigen Sie die entsprechende Seite an und drücken Sie alle Anzeigetasten Verwenden Sie beautifulsoup, um die erforderlichen Elemente zu erhalten (diesmal zwei Typen, Name und Adresse des Geschäfts). Formen Sie die Daten mit Pandas
main.py
#It is python3's app
#install selenium, beautifulsoup4, pandas with pip3
#download firefox, geckodriver
from selenium import webdriver
#from selenium.webdriver.firefox.options import Options
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
from bs4 import BeautifulSoup
import pandas as pd
import time
import re
import csv
import PySimpleGUI as sg
#plese download browserdriver and writedown driver's path
#bdriverpath='./chromedriver'
bdriverpath="C:\chromedriver.exe"
#make popup window
layout= [
[sg.Text('Area >> ', size=(15,1)), sg.InputText('Machida')],
[sg.Text('Keyword >> ', size=(15,1)), sg.InputText('Gemischtwarenladen')],
[sg.Submit(button_text='OK')]
]
window = sg.Window('Area and Keyword', layout)
#popup
while True:
event, values = window.read()
if event is None:
print('exit')
break
if event == 'OK':
show_message = "Area is " + values[0] + "\n"
show_message += "Keyword is " + values[1] + "\n"
print(show_message)
sg.popup(show_message)
break
window.close()
area =values[0]
keyword = values[1]
#initialize webdriver
options = Options()
options.add_argument('--headless')
driver=webdriver.Chrome(options=options, executable_path=bdriverpath)
#search page with keyword and area
driver.get('https://itp.ne.jp')
driver.find_element_by_id('keyword-suggest').find_element_by_class_name('a-text-input').send_keys(keyword)
driver.find_element_by_id('area-suggest').find_element_by_class_name('a-text-input').send_keys(area)
driver.find_element_by_class_name('m-keyword-form__button').click()
time.sleep(5)
#find & click readmore button
try:
while driver.find_element_by_class_name('m-read-more'):
button = driver.find_element_by_class_name('m-read-more')
button.click()
time.sleep(1)
except NoSuchElementException:
pass
res = driver.page_source
driver.quit()
#output with html
with open(area + '_' + keyword + '.html', 'w', encoding='utf-8') as f:
f.write(res)
#parse with beautifulsoup
soup = BeautifulSoup(res, "html.parser")
shop_names = [n.get_text(strip=True) for n in soup.select('.m-article-card__header__title')]
shop_locates = [n.get_text(strip=True) for n in soup.find_all(class_='m-article-card__lead__caption', text=re.compile("Adresse"))]
#incorporation lists with pandas
df = pd.DataFrame([shop_names, shop_locates])
df = df.transpose()
#output with csv
df.to_csv(area + '_' + keyword + '.csv', quoting=csv.QUOTE_NONE, index=False, encoding='utf_8_sig')
sg.popup("finished")
Das Folgende ist eine Gruppe von Bibliotheken, die diesmal nicht funktionieren. Alle können mit pip3 installiert werden. Der Teil, der auskommentiert wird, ist, ob Chrom oder Firefox verwendet werden soll. Schreiben Sie ihn daher bitte entsprechend Ihrem Geschmack und Ihrer Umgebung neu.
import.py
from selenium import webdriver
#from selenium.webdriver.firefox.options import Options
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
from bs4 import BeautifulSoup
import pandas as pd
import time
import re
import csv
import PySimpleGUI as sg
driver Um den unten beschriebenen Webdriver verwenden zu können, benötigen Sie einen Chromedriver für Chrome und einen Geckodriver für Firefox. Bitte laden Sie die entsprechende von der folgenden Website herunter. https://github.com/mozilla/geckodriver/releases https://chromedriver.chromium.org/downloads Derzeit funktioniert es auch nur, wenn die von Ihnen verwendeten Versionen ** Browser, Python und Treiber 3 ** in Mesh sind.
driver.py
#plese download browserdriver and writedown driver's path
#bdriverpath='./chromedriver'
bdriverpath="C:\chromedriver.exe"
PySimpleGUI Verweise Wenn Sie Tkinter verwenden, versuchen Sie es mit PySimpleGUI
Legen Sie das Layout fest und schreiben Sie die Standardeingabe (Machida, Convenience Store).
layout.py
#make popup window
layout= [
[sg.Text('Area >> ', size=(15,1)), sg.InputText('Machida')],
[sg.Text('Keyword >> ', size=(15,1)), sg.InputText('Gemischtwarenladen')],
[sg.Submit(button_text='OK')]
]
window.py
window = sg.Window('Area and Keyword', layout)
#popup
while True:
event, values = window.read()
if event is None:
print('exit')
break
if event == 'OK':
show_message = "Area is " + values[0] + "\n"
show_message += "Keyword is " + values[1] + "\n"
print(show_message)
sg.popup(show_message)
break
window.close()
area =values[0]
keyword = values[1]
Webdriver (Selen) ist eine Bibliothek zum programmgesteuerten Betrieb normaler Browser (Firefox, Chrome usw.).
Fügen Sie zunächst "--headless" zu den Startoptionen hinzu. Dies ist eine Option, um den Browser im Hintergrund auszuführen.
Wenn der Browser automatisch funktionieren soll, kommentieren Sie options.add_argument ('--headless')
aus.
Starten Sie dann Chrome mit "driver = webdriver.Chrome ()".
Geben Sie gleichzeitig die Option und den Treiberpfad ein. options = options, executeable_path = briverpath
init.py
#initialize webdriver
options = Options()
options.add_argument('--headless')
driver=webdriver.Chrome(options=options, executable_path=briverpath)
Gehen Sie mit driver.get
zum Anfang der Stadtseite.
Suchen Sie das Eingabefeld für die Eingabe von Schlüsselwörtern und Bereichen in "driver.find ~" und geben Sie auch ".send_keys ()" ein.
Suchen Sie die Suchstartschaltfläche auf die gleiche Weise und drücken Sie die Schaltfläche mit .click ()
.
search.py
#search page with keyword and area
driver.get('https://itp.ne.jp')
driver.find_element_by_id('keyword-suggest').find_element_by_class_name('a-text-input').send_keys(keyword)
driver.find_element_by_id('area-suggest').find_element_by_class_name('a-text-input').send_keys(area)
driver.find_element_by_class_name('m-keyword-form__button').click()
time.sleep(5)
Auf der folgenden Seite hat das Schlüsselworteingabefeld beispielsweise die ID "Schlüsselwortvorschlag" und eine Klasse "Texteingabe".
keyword.html
<div data-v-1wadada="" id="keyword-suggest" class="m-suggest" data-v-1dadas14="">
<input data-v-dsadwa3="" type="text" autocomplete="off" class="a-text-input" placeholder="Geben Sie ein Stichwort ein" data-v-1bbdb50e="">
<!---->
</div>
Verwenden Sie eine Schleife, um die Mehranzeigetaste class_name = m-read-more
so lange zu drücken, wie Sie sie finden.
Wenn Sie versuchen, dieselbe Schaltfläche unmittelbar nach dem Drücken der Schaltfläche zu finden, wird die neue Schaltfläche noch nicht geladen und endet in der Mitte. Stellen Sie daher eine Wartezeit mit "time.sleep (1)" ein
Wenn die Schaltfläche nicht gefunden wird, verursacht der Web-Treiber einen Fehler und das Programm wird beendet. Sagen Sie den Fehler daher im Voraus voraus.
Fahren Sie nach dem Ausnehmen mit dem nächsten fort, und setzen Sie das erhaltene HTML (die gesamte Anzeige ist gedrückt) in "res", "driver.quit ()"
Der Webtreiber wird beendet
button.py
from selenium.common.exceptions import NoSuchElementException
#find & click readmore button
try:
while driver.find_element_by_class_name('m-read-more'):
button = driver.find_element_by_class_name('m-read-more')
button.click()
time.sleep(1)
except NoSuchElementException:
pass
res = driver.page_source
driver.quit()
Nur für den Fall, ich werde das HTML ausgeben, das ich habe. Nicht benötigt
html.py
#output with html
with open(area + '_' + keyword + '.html', 'w', encoding='utf-8') as f:
f.write(res)
Übergeben Sie das HTML, das Sie zuvor erhalten haben, an beautifulsoup.
Suchen Sie nach einem Element mit "oup.select "und erhalten Sie nur den Geschäftsnamen (Adresse) mit" .get_text () ".
Wenn Sie nur "get_text ()" verwenden, werden Zeilenumbrüche und Leerzeichen eingefügt. Wenn Sie jedoch die Option "strip = True" hinzufügen, erhalten Sie nur die gewünschten Zeichen.
In Bezug auf die Adresse wurde auf der Seite der Stadtseite die Klasse class_name = m-article-card__lead__caption
nicht nur für die Adresse, sondern auch für die Telefonnummer und die nächste Station festgelegt, sodass nur die Adresse durch Zeichenfolge extrahiert werden kann. Ich habe es. text = re.compile (" address ")
parse.py
#parse with beautifulsoup
soup = BeautifulSoup(res, "html.parser")
shop_names = [n.get_text(strip=True) for n in soup.select('.m-article-card__header__title')]
shop_locates = [n.get_text(strip=True) for n in soup.find_all(class_='m-article-card__lead__caption', text=re.compile("Adresse"))]
Ich benutze Pandas, um die Daten zu ordnen. Die von beautifulsoup erhaltenen Daten sind eine Liste, kombinieren Sie also beide. Dies allein führt zu Landschaftsdaten. Verwenden Sie also "transponieren ()", um ein Porträt zu erstellen.
pandas.py
#incorporation lists with pandas
df = pd.DataFrame([shop_names, shop_locates])
df = df.transpose()
Dieses Mal gebe ich es im CSV-Format aus. Verwenden Sie den vom Benutzer eingegebenen Bereich und das Schlüsselwort für den Dateinamen. Wenn die Pandas-Daten ausgegeben werden, werden sie vertikal nummeriert, aber da es sich um ein Hindernis handelt, werden sie mit "index = False" gelöscht. Wenn Sie die Ausgabedaten in Excel öffnen, tritt das Problem auf, dass die Zeichen verstümmelt sind. Verwenden Sie daher "encoding =" utf_8_sig ", um dies zu vermeiden.
csv.py
#output with csv
df.to_csv(area + '_' + keyword + '.csv', quoting=csv.QUOTE_NONE, index=False, encoding='utf_8_sig')
Ich habe versucht, das Netz mit Selen abzukratzen, aber der Eindruck war, dass der Betrieb nicht stabil war. Da der Browser tatsächlich ausgeführt wird, kann der Vorgang nach dem Laden oder Drücken der Taste nicht garantiert werden. Dieses Mal habe ich "time.sleep" verwendet, um dies zu vermeiden. (Ich habe ursprünglich das implizite / explizite Warten von Selen verwendet, aber es hat bei mir nicht funktioniert.) Als ich den Webdriver heruntergeladen habe, war es aus irgendeinem Grund eine alte Version, und ich hatte ungefähr 2 Tage lang einen Fehler, ohne es zu bemerken, also war ich (für mich selbst) sehr wütend.
Recommended Posts