[PYTHON] I-Town-Seite mit Selen abkratzen

Vorwort

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

Hinweis

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

Ich Stadt Seite

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.

Programmübersicht

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")

Erklärung für jeden Block

Umgebung

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.


Übergeben Sie nach dem Herunterladen des Treibers den Pfad als Umgebungsvariable oder platzieren Sie ihn an einem leicht verständlichen Ort und schreiben Sie den Pfad in das Programm. In meiner Windows-Umgebung befindet es sich direkt unter dem Laufwerk C. Ich habe es auskommentiert, aber unter Linux (Mac) habe ich es an der gleichen Stelle abgelegt, an der das Programm abgelegt und verwendet wurde.

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')]
]

Erstellen Sie ein Fenster und laden Sie es in einer Schleife. Wenn die OK-Taste im Fenster gedrückt wird, wird der Eingabeinhalt in Werte [] eingelesen. Beenden Sie nach Abschluss der Verarbeitung mit window.close () und übergeben Sie den Eingabeinhalt an die Variablen im Programm.

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]

Starten Sie den Webdriver

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)

Suche mit Webdriver

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)

HTML-Beispiel

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>

Schieben Sie das Display weiter

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

HTML ausgeben

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)

HTML-Analyse

Ü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"))]

Datenformung

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

Datenausgabe

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')

Am Ende

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

I-Town-Seite mit Selen abkratzen
Schaben mit Selen
Schaben mit Selen
Erfolgreiches Schaben mit Selen
Schaben mit Selen [Python]
Schaben mit Selen in Python
Schaben mit Selen + Python Teil 1
Schaben mit Selen + Python Teil 2
Scraping mit Selen in Python (Basic)
Scraping mit Python
Scraping mit Python
Beginnend mit Selen
[Persönlicher Hinweis] Scraping von Webseiten in Python3
Üben des Web-Scrapings mit Python und Selen
WEB-Scraping mit BeautifulSoup4 (Seriennummernseite)
i-Town Page Scraping: Ich wollte den Platz von Wise-Kun einnehmen
Scraping in Python (Vorbereitung)
Versuchen Sie es mit Python.
Scraping mit Python + PhantomJS
Schaben mit kratzender Schale
Screenshot mit Selen (Python Edition)
Scraping mit Python + PyQuery
Kratzen mit schöner Suppe
Scraping von RSS mit Python
Ich war süchtig danach, 2020 mit Selen (+ Python) zu kratzen
Iframe in Seite mit Selenium kann nicht bearbeitet werden
Ich habe versucht, mit Python zu kratzen
Laden Sie Bilder automatisch mit Scraping herunter
Web Scraping mit Python + JupyterLab
Festliches Scraping mit Python, Scrapy
Speichern Sie Bilder mit Web Scraping
Python: Arbeiten mit Firefox mit Selen
Scraping mit Tor in Python
Web Scraping mit Selenium (Python)
Kratzwettervorhersage mit Python
Erinnerungen an den Kampf mit Selen
Schaben Nikkei Durchschnitt mit Dramatiker-Python
Probieren Sie Selenium Grid mit Docker aus
[Python + Selen] Tipps zum Scraping
Ich habe versucht, mit Python zu kratzen
Web Scraping Anfänger mit Python
Tischkratzen mit schöner Suppe
[Python, Selenium, PhantomJS] Eine Geschichte beim Scrapen einer Website mit fauler Last
Ich habe versucht, mich automatisch mit Selen bei Twitter anzumelden (RPA, Scraping)
Versuchen Sie es mit Python + Beautiful Soup
Scraping mit Node, Ruby und Python
Zusammenfassung der Kratzbeziehung (Selen, Pyautogui)
Web Scraping mit Python Erster Schritt
Ich habe versucht, WebScraping mit Python.
Kratzen mit Python und schöner Suppe
Kratzen mit schöner Suppe in 10 Minuten
Vertrauteres Testen mit Selen
Lassen Sie uns mit Python Image Scraping durchführen
Scraping der SBI Securities-Portfolio-Seite
"Scraping & maschinelles Lernen mit Python" Lernnotiz