Scraping mit Python, Posting auf TwitterBot, regelmäßige Ausführung auf Heroku

Ich habe versucht, mit Python zu kratzen und regelmäßig mit Heroku auf TwitterBot zu posten.

・ Weil ich unter Klingeln in meinen Ohren leide, einem Bot, der regelmäßig Informationen über "Klingeln in meinen Ohren" twittert. · Mac ・ Python3 Insbesondere habe ich eine Anwendung erstellt, die die folgenden beiden ausführt. [1] Scraping Suchergebnisse für "Klingeln" und "Blenden" von Yahoo News und regelmäßiges Tweeten [2] Tweets wie "Verbesserung des Ohrens" und "Ursache des Ohrens" regelmäßig retweeten (gut)

* Umgebungskonstruktion, Verzeichnisstruktur

Erstellen Sie ein Verzeichnis miminari auf Ihrem Desktop und erstellen Sie die Datei Scraping.py. Erstellen und starten Sie eine virtuelle Umgebung wie folgt.

python3 -m venv .
source bin/activate

Installieren Sie die erforderlichen Module.

pip install requests
pip install beautifulsoup4
pip install lxml

Verzeichnisaufbau

miminari
├scraping.py
├date_list.txt
├source_list.txt
├text_list.txt
├title_list.txt
├url_list.txt
├twitter.py
├Procfile
├requirements.txt
└runtime.txt

[1] Scraping "Klingeln" und "Blenden" von Yahoo News und regelmäßiges Tweeten

(1) Erstellen Sie Scraping.py

① Verschrotten des Nachrichtentitels und der URL

Suchen Sie in Yahoo News nach "Klingeln" und "Blenden" und kopieren Sie die URL. Die Seite zeigt 10 Nachrichten. Suchen Sie einen wahrscheinlichen Speicherort für den Titel und die URL. Wenn Sie sich die "Überprüfung" von Google Chrome ansehen, sehen Sie, dass sie in der Klasse = t des h2-Tags enthalten ist. Auf dieser Grundlage werde ich den Code schreiben. スクリーンショット 2020-03-21 19.15.50.png

.py:scraping.py


from bs4 import BeautifulSoup
import lxml
import requests

URL = "https://news.yahoo.co.jp/search/?p=%E8%80%B3%E9%B3%B4%E3%82%8A+%E3%82%81%E3%81%BE%E3%81%84&oq=&ei=UTF-8&b=1"

res = requests.get(URL)
res.encoding = res.apparent_encoding
html_doc = res.text
soup = BeautifulSoup(html_doc,"lxml")

list = soup.find_all("h2",class_="t")
print(list)

Dann können Sie es im Listenformat wie folgt erhalten.

[<h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200320-00000019-nkgendai-hlth">Misono bekämpft auch Krankheit Morbus Menière Es wurde keine radikale Heilung gefunden, aber wie gehen Sie damit um?</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200316-00010000-flash-ent">Shoko Aida leidet an plötzlichem Hörverlust und Morbus Menière<em>Klingeln in den Ohren</em>Aber…"</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200315-00000004-nikkeisty-hlth">Gluten verärgert, Behandlung ist ohne Anleitung gefährlich</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200313-00000243-spnannex-ent">Shoko Aida gesteht ihre Krankheit, sich zum ersten Mal aus der Unterhaltungswelt zurückzuziehen. Dank der "mentalen Betreuung" des Arztes</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200310-00000011-pseven-life">"Hörverlust" ist ein Risikofaktor für Demenz Depressionsrisiko 2.Daten mit 4 mal</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200309-00010009-nishispo-spo">Der Klassenkamerad des olympischen Vertreters Ohno überwindet die Krankheit und geht wahllos auf die große Bühne der 81 kg schweren Klasse</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200226-00010011-newsweek-int">Die mysteriöse Schockwelle des Iran, die das US-Militär getroffen hat, wird mehrere Jahre dauern, bis sie sich aufgelöst hat</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200223-00986372-jspa-life">Ich bin aufgrund meiner Krankheit und Fruchtbarkeit in einem Krankheitszustand ...</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200215-00001569-fujinjp-life">Unzureichende Wärmeenergie? Stagnation der Durchblutung? Kennen Sie die Art der "Kälte" und werden Sie ein Körper, der der Kälte standhalten kann</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200214-00010009-jisin-soci">Von Ärzten empfohlen! Schlaflosigkeit, Menstruationsbeschwerden, Kopfschmerzen ... "Normale Hitze 36."5 Grad" verhindert Störungen</a></h2>]

Ergänzende Erklärung

-Encoding ist die Zeichencodierung der vom Server zurückgegebenen Antwort. Der Inhalt wird gemäß dieser Zeichenkodierung konvertiert. -Apparent_encoding bedeutet einen Prozess, mit dem der Inhalt erfasst werden kann, damit keine verstümmelten Zeichen auftreten. -Lxml ist einer der HTML-Parser, der HTML-Phrasen analysiert, Tags ermittelt usw. und diese als Datenstruktur erfasst. Normalerweise benutze ich html.parser. Dieses Mal werden wir lxml als schnelleren Parser verwenden. lxml muss separat installiert und importiert werden.

② Scraping des Nachrichtentitels und der URL (in Datei speichern)

.py:scraping.py


from bs4 import BeautifulSoup
import lxml
import requests

URL = "https://news.yahoo.co.jp/search/?p=%E8%80%B3%E9%B3%B4%E3%82%8A+%E3%82%81%E3%81%BE%E3%81%84&oq=&ei=UTF-8&b=1"
res = requests.get(URL)
html_doc = res.text
soup = BeautifulSoup(html_doc,"lxml")


#Titel und URL abrufen------------------------------
_list = soup.find_all("h2",class_="t")
title_list = []
url_list = []
for i in _list:
    a_tag = i.find_all('a')
    for _tag in a_tag:
        #Titel extrahieren, erhalten_text()Extrahiert die in Tags eingeschlossene Zeichenfolge
        href_text = _tag.get_text()
        #Erstellen Sie eine Liste mit extrahierten Titeln
        title_list.append(href_text)
        #get("href")Extrahiert die in Tags enthaltene URL
        url_text = _tag.get("href")
        #Erstellen Sie eine Liste mit extrahierten Titeln
        url_list.append(url_text)

#Im Textformat speichern
with open('title_data'+'.txt','a',encoding='utf-8') as f:
    for i in title_list:
        f.write(i + '\n')
with open('url_data'+'.txt','a',encoding='utf-8') as f:
    for i in url_list:
        f.write(i + '\n')

Ergänzende Erklärung

-Get.text () kann die in Tags eingeschlossene Zeichenfolge extrahieren. -Get ("href") kann den Attributwert abrufen.

③ Verschrotten der Nachrichtenzusammenfassung (Text), des Datums und der Uhrzeit sowie der Quelle

Verschrotten Sie die Nachrichtenzusammenfassung sowie Datum und Uhrzeit auf die gleiche Weise und speichern Sie jede einzelne.

.py:scraping.py


from bs4 import BeautifulSoup
import lxml
import requests

URL = "https://news.yahoo.co.jp/search/?p=%E8%80%B3%E9%B3%B4%E3%82%8A+%E3%82%81%E3%81%BE%E3%81%84&oq=&ei=UTF-8&b=1"
res = requests.get(URL)
html_doc = res.text
soup = BeautifulSoup(html_doc,"lxml")


#Titel und URL abrufen------------------------------
_list = soup.find_all("h2",class_="t")
title_list = []
url_list = []
for i in _list:
    a_tag = i.find_all('a')
    for _tag in a_tag:
        #Titel extrahieren, erhalten_text()Extrahiert die in Tags eingeschlossene Zeichenfolge
        href_text = _tag.get_text()
        #Erstellen Sie eine Liste mit extrahierten Titeln
        title_list.append(href_text)
        #get("href")Extrahiert die in Tags enthaltene URL
        url_text = _tag.get("href")
        #Erstellen Sie eine Liste mit extrahierten Titeln
        url_list.append(url_text)

with open('title_data'+'.txt','a',encoding='utf-8') as f:
    for i in title_list:
        f.write(i + '\n')
with open('url_data'+'.txt','a',encoding='utf-8') as f:
    for i in url_list:
        f.write(i + '\n')


#Text abrufen-----------------------------------------
_list2 = soup.find_all("p",class_="a")
text_list = []
for i in _list2:
    text_text = i.get_text()
    text_list.append(text_text)
with open('text_list'+'.txt','a',encoding='utf-8')as f:
    for i in text_list:
        f.write(i + '\n')


#Holen Sie sich Datum und Uhrzeit---------------------------------------------------------------
_list3 = soup.find_all("span",class_="d")
date_list = []
for i in _list3:
    _date_text = i.get_text()
    _date_text = _date_text.replace('\xa0','')
    date_list.append(_date_text)
with open('date_list'+'.txt','a',encoding='utf-8') as f:
    for i in date_list:
        f.write(i + '\n')


#Holen Sie sich die Quelle---------------------------------------------------------------
    _list4 = soup.find_all("span",class_="ct1")
    source_list = []
    for i in _list4:
        _source_text = i.get_text()
        source_list.append(_source_text)
    with open('source_list'+'.txt','a',encoding='utf-8') as f:
        for i in source_list:
            f.write(i + '\n')

Ergänzende Erklärung

-Obwohl es sich um Datum und Uhrzeit handelt, wird beim Extrahieren auch das zusätzliche Zeichen "& nbsp" extrahiert, sodass es mit replace ersetzt wird (beim Scraping wird "& nbsp" als "\ xa0" geschrieben). Daher wurde es ersetzt ('\ xa0', ''). スクリーンショット 2020-03-21 21.51.42.png

④ Schaben ab der nächsten Seite

Wenn dies unverändert bleibt, werden nur 10 Nachrichten für eine Seite abgekratzt. Drehen Sie dies also für 4 Seiten um (da das Umblättern von 4 Seiten bedeutet, dass die Nachrichtensuchergebnisse für "Ohrensausen" und "Blenden" nur 4 Seiten waren). .. Ändern Sie den Code wie folgt.

.py:scraping.py


from bs4 import BeautifulSoup
import lxml
import requests

mm = 0
for i in range(4):
    URL = "https://news.yahoo.co.jp/search/?p=%E8%80%B3%E9%B3%B4%E3%82%8A+%E3%82%81%E3%81%BE%E3%81%84&oq=&ei=UTF-8&b={}".format(mm*10 + 1)
    res = requests.get(URL)
    html_doc = res.text
    soup = BeautifulSoup(html_doc,"lxml")

    #Titel und URL abrufen------------------------------
    _list = soup.find_all("h2",class_="t")
    title_list = []
    url_list = []
    for i in _list:
        a_tag = i.find_all('a')
        for _tag in a_tag:
            #Titel extrahieren, erhalten_text()Extrahiert die in Tags eingeschlossene Zeichenfolge
            href_text = _tag.get_text()
            #Erstellen Sie eine Liste mit extrahierten Titeln
            title_list.append(href_text)
            #get("href")Extrahiert die in Tags enthaltene URL
            url_text = _tag.get("href")
            #Erstellen Sie eine Liste mit extrahierten Titeln
            url_list.append(url_text)

    with open('title_list'+'.txt','a',encoding='utf-8') as f:
        for i in title_list:
            f.write(i + '\n')
    with open('url_list'+'.txt','a',encoding='utf-8') as f:
        for i in url_list:
            f.write(i + '\n')


    #Text abrufen-----------------------------------------
    _list2 = soup.find_all("p",class_="a")
    text_list = []
    for i in _list2:
        text_text = i.get_text()
        text_list.append(text_text)
    with open('text_list'+'.txt','a',encoding='utf-8')as f:
        for i in text_list:
            f.write(i + '\n')


    #Datum (und Uhrzeit,---------------------------------------------------------------
    _list3 = soup.find_all("span",class_="d")
    date_list = []
    for i in _list3:
        _date_text = i.get_text()
        _date_text = _date_text.replace('\xa0','')
        date_list.append(_date_text)
    with open('date_list'+'.txt','a',encoding='utf-8') as f:
        for i in date_list:
            f.write(i + '\n')


    #Quelle---------------------------------------------------------------
    _list4 = soup.find_all("span",class_="ct1")
    source_list = []
    for i in _list4:
        _source_text = i.get_text()
        source_list.append(_source_text)
    with open('source_list'+'.txt','a',encoding='utf-8') as f:
        for i in source_list:
            f.write(i + '\n')

    #mm-------------------------------------------------------------------
    mm += 1

Ergänzende Erklärung

Die folgenden Teile wurden hinzugefügt. Da das Ende der URL für jede Seite 1, 11, 21 und 31 ist, wurde sie mit der for-Anweisung und dem Format verarbeitet.

mm = 0
for i in range(4): 〜〜〜〜

〜〜〜〜 q=&ei=UTF-8&b={}".format(mm*10 + 1)

〜〜〜〜
mm += 1

Bis zu diesem Zeitpunkt wurden beim Scraping der Titel (title_list), die URL (url_list), die Zusammenfassung (text_list), das Datum und die Uhrzeit (date_list) sowie die Quelle (source_list) jeder Nachricht erstellt. Danach werde ich mit dem Posten auf Twitter fortfahren, aber ich habe nur das Datum und die Uhrzeit (Datumsliste), die Quelle (Quellenliste) und die URL (URL-Liste) verwendet.

(2) Auf Twitter posten

Dieses Mal werde ich die detaillierte Methode zum Erstellen von TwitterBot weglassen. Beim Erstellen eines Bots habe ich im Folgenden darauf hingewiesen, wie Sie sich bei der Twitter-API registrieren und auf Twitter twittern können. Zusammenfassung der Schritte von der Registrierung der Twitter-API (Kontoanwendungsmethode) bis zur Genehmigung Auf Twitter auf Tweepy posten Suche Twitter auf Tweepy, wie, retweet

Erstellen Sie twitter.py im Verzeichnis miminari und installieren Sie Tweepy.

pip install tweeps

Erstellen Sie twitter.py wie folgt

.py:twitter.py


import tweepy
from random import randint
import os

auth = tweepy.OAuthHandler(os.environ["CONSUMER_KEY"],os.environ["CONSUMER_SECRET"])
auth.set_access_token(os.environ["ACCESS_TOKEN"],os.environ["ACCESS_TOKEN_SECERET"])

api = tweepy.API(auth)

twitter_source =[]
twitter_url = []
twitter_date = []

with open('source_list.txt','r')as f:
    for i in f:
        twitter_source.append(i.rstrip('\n'))
with open('url_list.txt','r')as f:
    for i in f:
        twitter_url.append(i.rstrip('\n'))
with open('date_list.txt','r')as f:
    for i in f:
        twitter_date.append(i.rstrip('\n'))

#Extrahieren Sie Artikel mit den Funktionen randint und len nach dem Zufallsprinzip aus dem 0. bis n-1. Bereich der Liste
i = randint(0,len(twitter_source)-1)
api.update_status("<Nachrichten zum Klingeln in den Ohren>" + '\n' + twitter_date[i] + twitter_source[i] + twitter_url[i])

Ergänzende Erklärung

-Consumer_KEY usw. werden basierend auf der Bereitstellung in Heroku als Umgebungsvariablen festgelegt. -Artikel werden jetzt zufällig getwittert.

[2] Tweets wie "Verbesserung des Ohrens" und "Ursache des Ohrens" regelmäßig retweeten (gut)

Fügen Sie Code zu twitter.py hinzu

.py:twitter.py


import tweepy
from random import randint
import os


#auth = tweepy.OAuthHandler(config.CONSUMER_KEY,config.CONSUMER_SECRET)
#auth.set_access_token(config.ACCESS_TOKEN,config.ACCESS_TOKEN_SECERET)

auth = tweepy.OAuthHandler(os.environ["CONSUMER_KEY"],os.environ["CONSUMER_SECRET"])
auth.set_access_token(os.environ["ACCESS_TOKEN"],os.environ["ACCESS_TOKEN_SECERET"])

api = tweepy.API(auth)


#-Yahoo_Nachrichten (Ohrensausen, Schwindel) Tweet-Verarbeitung----------------------------------------------
twitter_source =[]
twitter_url = []
twitter_date = []

with open('source_list.txt','r')as f:
    for i in f:
        twitter_source.append(i.rstrip('\n'))
with open('url_list.txt','r')as f:
    for i in f:
        twitter_url.append(i.rstrip('\n'))
with open('date_list.txt','r')as f:
    for i in f:
        twitter_date.append(i.rstrip('\n'))

#Extrahieren Sie Artikel mit den Funktionen randint und len nach dem Zufallsprinzip aus dem 0. bis n-1. Bereich der Liste
i = randint(0,len(twitter_source)-1)
api.update_status("<Nachrichten zum Klingeln in den Ohren>" + '\n' + twitter_date[i] + twitter_source[i] + twitter_url[i])




#-(Folgendes wird hinzugefügt) Retweet-Verarbeitung----------------------------------------------------------------------
search_results_1 = api.search(q="Verbesserung des Ohrens", count=10)
search_results_2 = api.search(q="Schreckliches Klingeln in den Ohren", count=10)
search_results_3 = api.search(q="Klingelnde Ohren", count=10)
search_results_4 = api.search(q="Ohrringmedizin", count=10)
search_results_5 = api.search(q="Was ist Ohrensausen?", count=10)
search_results_6 = api.search(q="Ursache des Klingelns in den Ohren", count=10)
search_results_7 = api.search(q="Klingeln in den Ohren", count=10)
search_results_8 = api.search(q="Ohrringtopf", count=10)
search_results_9 = api.search(q="Ohrensausen Kopfschmerzen", count=10)
search_results_10 = api.search(q="#Klingeln in den Ohren", count=10)
search_results_11 = api.search(q="Klingeln in den Ohren", count=10)

the_list = [search_results_1,
            search_results_2,
            search_results_3,
            search_results_4,
            search_results_5,
            search_results_6,
            search_results_7,
            search_results_8,
            search_results_9,
            search_results_10,
            search_results_11
            ]

for i in range(10):
  for result in the_list[i]:
      tweet_id = result.id
      #Ausnahmen behandeln. Es scheint, dass ein Fehler auftritt, wenn Sie Duplikate verarbeiten,
      #Wenn Sie die Ausnahmeverarbeitung verwenden, wird sie nicht in der Mitte des Programms gestoppt.
      try:
          api.retweet(tweet_id)#Retweet-Verarbeitung
          api.create_favorite(tweet_id) #Wie die Verarbeitung
      except Exception as e:
          print(e)

[3] In Heroku bereitstellen

(1) Bereitstellen

Erstellen Sie die für die Bereitstellung erforderliche Procfile, runtime.txt und require.txt. Erstellen Sie runtime.txt, nachdem Sie Ihre eigene Python-Version überprüft haben.

.txt:runtime.txt



python-3.8.0

Procfile beschreibt Folgendes.

Prockfile


web: python twitter.py

Beschreiben Sie die Datei "resources.txt", indem Sie im Terminal Folgendes eingeben.

pip freeze > requirements.txt

Stellen Sie als Nächstes Folgendes bereit. Initialisieren Sie git, verknüpfen Sie Heroku und git, fügen Sie den Namen zuerst hinzu und schreiben Sie ihn fest. Schieben Sie schließlich zu Heroku.

git init
heroku git:remote -a testlinebot0319
git add .
git commit -m'the-first'
git push heroku master

Wenn Sie Folgendes in das Terminal eingeben und es vor der regulären Ausführung auf Twitter veröffentlichen, ist es vorerst erfolgreich.

(2) Regelmäßige Ausführung

Führen Sie im Terminal die folgenden Schritte aus, um die regelmäßige Ausführung von Heroku direkt im Browser festzulegen.

heroku adding:add scheduler:standard
heroku adding:open scheduler
スクリーンショット 2020-03-22 0.15.55.png

Wenn Sie wie oben festlegen, wird der Vorgang abgeschlossen (oben ist die Tweet-Einstellung alle 10 Minuten).

abschließend

Wenn Sie möchten, folgen Sie mir bitte Twitter@MiminariBot

Recommended Posts

Scraping mit Python, Posting auf TwitterBot, regelmäßige Ausführung auf Heroku
Scraping mit Python
Scraping mit Python
Bis zur Verwendung von PhantomJS mit Python auf Heroku
Scraping in Python (Vorbereitung)
Versuchen Sie es mit Python.
Scraping mit Python + PhantomJS
Tweets mit Python posten
Schaben mit Selen [Python]
Scraping mit Python + PyQuery
Scraping von RSS mit Python
Ich habe versucht, regelmäßig E-Mails von sendgrid mit Heroku und Python zu senden
Ich habe versucht, mit Python zu kratzen
Web Scraping mit Python + JupyterLab
Betreiben Sie TwitterBot mit Lambda, Python
Schaben mit Selen + Python Teil 1
Schaben mit Chromedriver in Python
Festliches Scraping mit Python, Scrapy
Scraping mit Selen in Python
Scraping mit Tor in Python
Messung der Ausführungszeit mit Python With
Kratzwettervorhersage mit Python
Manipulation regulärer Ausdrücke durch Python
Schaben mit Selen + Python Teil 2
Ich habe versucht, mit Python zu kratzen
Web Scraping Anfänger mit Python
So stellen Sie cron für reguläres Python-Scraping auf dem Sakura-Server ein.
Versuchen Sie es mit Python + Beautiful Soup
Erstelle einen LINE-Bot mit Python + Heroku
Scraping mit Node, Ruby und Python
Scraping mit Selen in Python (Basic)
Scraping mit Python, Selen und Chromedriver
Web Scraping mit Python Erster Schritt
Ich habe versucht, WebScraping mit Python.
Kratzen mit Python und schöner Suppe
Python + Django + Scikit-Learn + Mecab (1) mit Heroku
String-Ersetzung durch regulären Python-Ausdruck
Python + Django + Scikit-Learn + Mecab (2) mit Heroku
Lassen Sie uns mit Python Image Scraping durchführen
Problem mit Python json.loads (), das str in Heroku zurückgibt
Regelmäßiges Serverless Scraping mit AWS Lambda + Scrapy Teil 1
Holen Sie sich Qiita-Trends mit Python-Scraping
Hinweise zur Verwendung von rstrip mit Python.
Erste Schritte mit Python 3.8 unter Windows
Einfache parallele Ausführung mit Python-Unterprozess
"Scraping & maschinelles Lernen mit Python" Lernnotiz
Umgang mit regulären Ausdrücken durch PHP / Python
Holen Sie sich Wetterinformationen mit Python & Scraping
[Memo] Tweet auf Twitter mit Python
Führen Sie Python regelmäßig auf Heroku Scheduler aus
Abrufen von Eigenschaftsinformationen durch Scraping mit Python
Führen Sie das Servo mit Python unter ESP32 (Windows) aus.
Automatisieren Sie einfache Aufgaben mit Python Part1 Scraping
Erste Schritte mit Python Web Scraping Practice
Lassen Sie Heroku die Hintergrundverarbeitung mit Python durchführen
Ein Memo mit Python2.7 und Python3 in CentOS
Kartenmietinformationen auf einer Karte mit Python
Verfolgen Sie aktive Anwendungen auf einem Mac mit Python
[C] [Python] Lesen mit AquesTalk unter Linux