Scraping avec Python, publication sur TwitterBot, exécution régulière sur Heroku

J'ai essayé de gratter avec Python et de publier régulièrement sur TwitterBot avec Heroku.

・ Parce que je souffre de bourdonnements dans mes oreilles, un bot qui tweete régulièrement des informations sur "les bourdonnements dans mes oreilles". · Mac ・ Python3 -Spécifiquement, j'ai créé une application qui exécute les deux suivantes. [1] Grattage des résultats de recherche pour "sonnerie" et "éblouissant" de Yahoo News et tweet régulièrement [2] Retweetez régulièrement des tweets tels que "amélioration du bourdonnement d'oreille" et "cause du bourdonnement d'oreille" (bon)

* Construction de l'environnement, structure de répertoires

Créez un répertoire miminari sur votre bureau et créez scraping.py. Créez et démarrez un environnement virtuel comme suit.

python3 -m venv .
source bin/activate

Installez les modules requis.

pip install requests
pip install beautifulsoup4
pip install lxml

Structure du répertoire

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] Gratter "sonnerie" et "éblouissant" de Yahoo News et tweet régulièrement

(1) Créez scraping.py

① Gratter le titre et l'URL de l'actualité

Recherchez "sonnerie" et "éblouissant" dans Yahoo News et copiez l'URL. Le site présente 10 actualités. Trouvez un emplacement probable pour le titre et l'URL. Si vous regardez la "vérification" de Google Chrome, vous pouvez voir qu'il est dans la classe = t de la balise h2. Sur cette base, j'écrirai le code. スクリーンショット 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)

Ensuite, vous pouvez l'obtenir au format liste comme suit.

[<h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200320-00000019-nkgendai-hlth">misono lutte également contre la maladie Maladie de Ménière Aucun remède radical n'a été trouvé, mais comment y faire face?</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200316-00010000-flash-ent">Shoko Aida, passé souffrant d'une perte auditive soudaine et de la maladie de Ménière<em>Bourdonnement dans les oreilles</em>Mais…"</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200315-00000004-nikkeisty-hlth">Gluten bouleversé, le traitement est dangereux sans conseils</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200313-00000243-spnannex-ent">Shoko Aida avoue sa maladie pour se retirer du monde du divertissement pour la première fois. Grâce aux «soins mentaux» du médecin</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200310-00000011-pseven-life">La «perte auditive» est un facteur de risque de démence Risque de dépression 2.Données avec 4 fois</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200309-00010009-nishispo-spo">Le camarade de classe du représentant olympique Ohno surmonte la maladie et se rend sur la grande scène 81 kg défi sans discernement</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200226-00010011-newsweek-int">La mystérieuse onde de choc iranienne qui a frappé l'armée américaine, il faudra plusieurs années pour se démêler</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200223-00986372-jspa-life">Je suis en état de maladie à cause de ma maladie et de ma fertilité ... Je déchire les paroles que mon mari a données à ma femme</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/hl?a=20200215-00001569-fujinjp-life">Énergie thermique insuffisante? Stagnation de la circulation sanguine? Connaître le type de «froid» et devenir un corps capable de résister au froid</a></h2>, <h2 class="t"><a href="https://headlines.yahoo.co.jp/article?a=20200214-00010009-jisin-soci">Recommandé par les médecins! Insomnie, douleurs menstruelles, maux de tête ... "Chaleur normale 36."5 degrés" évite les bouleversements</a></h2>]

Explication supplémentaire

-Encoding est le codage de caractères de la réponse renvoyée par le serveur. Le contenu est converti selon ce codage de caractères. -Apparent_encoding signifie un processus permettant d'acquérir le contenu afin que les caractères déformés ne se produisent pas. -Lxml est l'un des analyseurs HTML qui analyse les phrases HTML, détermine les balises, etc., et les acquiert sous forme de structure de données. Normalement, j'utilise html.parser. Cette fois, nous utiliserons lxml comme analyseur plus rapide. lxml doit être installé et importé séparément. -Puisque le titre et l'URL se trouvent dans class = t de la balise h2 de la vérification de Google Chrome, nous le définissons comme find_all ("h2", class_ = "t").

② Gratter le titre et l'URL de l'actualité (enregistrer dans un fichier)

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


#Obtenir le titre et l'URL------------------------------
_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:
        #Extraire le titre, obtenir_text()Extrait la chaîne incluse dans les balises
        href_text = _tag.get_text()
        #Créer une liste avec les titres extraits
        title_list.append(href_text)
        #get("href")Extrait l'url incluse dans les balises
        url_text = _tag.get("href")
        #Créer une liste avec les titres extraits
        url_list.append(url_text)

#Enregistrer au format texte
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')

Explication supplémentaire

-Get.text () peut extraire la chaîne de caractères incluse dans les balises. -Get ("href") peut obtenir la valeur d'attribut.

③ Gratter le résumé de l'actualité (texte), la date et l'heure et la source

Supprimez le résumé de l'actualité, la date et l'heure de la même manière et enregistrez chacun d'eux.

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


#Obtenir le titre et l'URL------------------------------
_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:
        #Extraire le titre, obtenir_text()Extrait la chaîne incluse dans les balises
        href_text = _tag.get_text()
        #Créer une liste avec les titres extraits
        title_list.append(href_text)
        #get("href")Extrait l'url incluse dans les balises
        url_text = _tag.get("href")
        #Créer une liste avec les titres extraits
        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')


#Obtenir du texte-----------------------------------------
_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')


#Obtenir la date et l'heure---------------------------------------------------------------
_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')


#Obtenez la source---------------------------------------------------------------
    _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')

Explication supplémentaire

-Bien qu'il s'agisse de la date et de l'heure, s'il est extrait tel quel, le caractère supplémentaire "& nbsp" sera également extrait, il est donc effacé en utilisant replace (lorsqu'il est gratté, "& nbsp" s'écrit "\ xa0". Par conséquent, il a été remplacé ('\ xa0', ''). スクリーンショット 2020-03-21 21.51.42.png

④ Grattage à partir de la page suivante

Si cela est laissé tel quel, seuls 10 articles d'actualité pour une page feront l'objet d'un grattage, alors tournez-le sur 4 pages (car tourner 4 pages signifie que les résultats de la recherche d'actualités pour "oreille" et "éblouissant" ne représentaient que 4 pages). .. Modifiez le code comme suit.

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

    #Obtenir le titre et l'URL------------------------------
    _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:
            #Extraire le titre, obtenir_text()Extrait la chaîne incluse dans les balises
            href_text = _tag.get_text()
            #Créer une liste avec les titres extraits
            title_list.append(href_text)
            #get("href")Extrait l'url incluse dans les balises
            url_text = _tag.get("href")
            #Créer une liste avec les titres extraits
            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')


    #Obtenir du texte-----------------------------------------
    _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')


    #Date et l'heure,---------------------------------------------------------------
    _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')


    #La source---------------------------------------------------------------
    _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

Explication supplémentaire

Les parties suivantes ont été ajoutées. Comme la fin de l'URL est 1, 11, 21 et 31 pour chaque page, elle a été traitée à l'aide de l'instruction et du format for.

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

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

〜〜〜〜
mm += 1

Jusqu'à présent, le scraping a créé le titre (title_list), l'URL (url_list), le résumé (text_list), la date et l'heure (date_list) et la source (source_list) de chaque actualité. Après cela, je continuerai à publier sur Twitter, mais je n'ai utilisé que la date et l'heure (date_list), la source (source_list) et l'URL (url_list).

(2) Publier sur Twitter

Cette fois, je vais omettre la méthode détaillée de création de TwitterBot. Lors de la création d'un bot, je me suis référé à ce qui suit pour savoir comment s'inscrire à l'API Twitter et tweeter sur Twitter. Résumé des étapes de l'enregistrement de l'API Twitter (méthode de demande de compte) à l'approbation Publier sur Twitter sur Tweepy Recherche Twitter sur Tweepy, par exemple, retweet

Créez twitter.py dans le répertoire miminari et installez Tweepy.

pip install tweeps

Créez twitter.py comme suit

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

#Extrayez aléatoirement les articles de la plage 0 à n-1 de la liste avec les fonctions randint et len
i = randint(0,len(twitter_source)-1)
api.update_status("<Actualités liées aux bourdonnements d'oreilles>" + '\n' + twitter_date[i] + twitter_source[i] + twitter_url[i])

Explication supplémentaire

-Consumer_KEY etc. sont définis comme des variables d'environnement en fonction du déploiement sur Heroku. -Les articles sont maintenant tweetés au hasard.

[2] Retweetez régulièrement des tweets tels que "amélioration de la sonnerie d'oreille" et "cause de la sonnerie d'oreille" (bon)

Ajouter du code à twitter.py

.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_nouvelles (bourdonnements d'oreilles, étourdissements) Traitement des tweets----------------------------------------------
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'))

#Extrayez aléatoirement les articles de la plage 0 à n-1 de la liste avec les fonctions randint et len
i = randint(0,len(twitter_source)-1)
api.update_status("<Actualités liées aux bourdonnements d'oreilles>" + '\n' + twitter_date[i] + twitter_source[i] + twitter_url[i])




#-(Ce qui suit est ajouté) Traitement du retweet----------------------------------------------------------------------
search_results_1 = api.search(q="Amélioration de la sonnerie des oreilles", count=10)
search_results_2 = api.search(q="Terrible sonnerie dans les oreilles", count=10)
search_results_3 = api.search(q="Oreilles qui bourdonnent", count=10)
search_results_4 = api.search(q="Médecine de sonnerie d'oreille", count=10)
search_results_5 = api.search(q="Qu'est-ce que la sonnerie d'oreille?", count=10)
search_results_6 = api.search(q="Cause du bourdonnement dans les oreilles", count=10)
search_results_7 = api.search(q="Bourdonnement dans les oreilles", count=10)
search_results_8 = api.search(q="Pot de sonnerie d'oreille", count=10)
search_results_9 = api.search(q="Bourdonnements d'oreilles Maux de tête", count=10)
search_results_10 = api.search(q="#Bourdonnement dans les oreilles", count=10)
search_results_11 = api.search(q="Bourdonnement dans les oreilles", 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
      #Gérez les exceptions. Il semble qu'une erreur se produise si vous traitez les doublons,
      #Si vous utilisez le traitement des exceptions, il ne s'arrêtera pas au milieu du programme.
      try:
          api.retweet(tweet_id)#Traitement des retweets
          api.create_favorite(tweet_id) #Comme le traitement
      except Exception as e:
          print(e)

[3] Déployer sur Heroku

(1) Déployer

Créez le fichier Procfile, runtime.txt et requirements.txt requis pour le déploiement. Créez runtime.txt après avoir vérifié votre propre version de python.

.txt:runtime.txt



python-3.8.0

Procfile décrit ce qui suit.

Prockfile


web: python twitter.py

Décrivez requirements.txt en saisissant ce qui suit dans le terminal.

pip freeze > requirements.txt

Ensuite, déployez comme suit. Initialisez git, associez Heroku et git, ajoutez et validez avec le nom the-first. Poussez enfin vers Heroku.

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

Si vous entrez ce qui suit dans le terminal et que vous le publiez sur Twitter avant l'exécution régulière, cela réussira pour l'instant.

(2) Exécution périodique

Exécutez ce qui suit dans le terminal pour définir l'exécution périodique de Heroku directement sur le navigateur.

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

Si vous définissez comme ci-dessus, il sera terminé (ce qui précède est le réglage du tweet toutes les 10 minutes)

en conclusion

Si vous aimez, suivez-moi Twitter@MiminariBot

Recommended Posts

Scraping avec Python, publication sur TwitterBot, exécution régulière sur Heroku
Grattage avec Python
Grattage avec Python
Jusqu'à l'utilisation de PhantomJS avec Python sur Heroku
Grattage en Python (préparation)
Essayez de gratter avec Python.
Grattage avec Python + PhantomJS
Publier des tweets avec python
Grattage avec du sélénium [Python]
Scraping avec Python + PyQuery
Scraping RSS avec Python
J'ai essayé d'envoyer des courriels depuis sendgrid régulièrement avec heroku, avec python
J'ai essayé de gratter avec Python
Web scraping avec python + JupyterLab
Exploitez TwitterBot avec Lambda, Python
Grattage avec Selenium + Python Partie 1
Grattage avec chromedriver en python
Grattage festif avec Python, scrapy
Grattage avec du sélénium en Python
Grattage avec Tor en Python
Mesure du temps d'exécution avec Python avec
Scraping prévisions météorologiques avec python
Manipulation d'expressions régulières par Python
Grattage avec Selenium + Python Partie 2
J'ai essayé de gratter avec du python
Web scraping débutant avec python
Comment configurer cron pour le scraping Python normal sur le serveur Sakura.
Essayez de gratter avec Python + Beautiful Soup
Créez un bot LINE avec Python + heroku
Scraping avec Node, Ruby et Python
Scraping avec Selenium en Python (Basic)
Grattage avec Python, Selenium et Chromedriver
Web scraping avec Python Première étape
J'ai essayé webScraping avec python.
Grattage avec Python et belle soupe
python + django + scikit-learn + mecab (1) avec heroku
Remplacement de chaîne par une expression régulière Python
python + django + scikit-learn + mecab (2) avec heroku
Faisons du scraping d'images avec Python
Python json.loads () renvoie str dans Heroku
Grattage sans serveur régulier avec AWS lambda + scrapy, partie 1
Obtenez les tendances Qiita avec le scraping Python
Notes sur l'utilisation de rstrip avec python.
Premiers pas avec Python 3.8 sous Windows
Exécution parallèle facile avec le sous-processus python
Mémo d'apprentissage "Scraping & Machine Learning avec Python"
Gestion des expressions régulières par PHP / Python
Obtenez des informations météorologiques avec Python et le grattage
[Memo] Tweet sur Twitter avec Python
Exécutez régulièrement Python sur Heroku Scheduler
Obtenez des informations sur la propriété en grattant avec python
Exécutez le servo avec Python sur ESP32 (Windows)
Automatisez des tâches simples avec Python Part1 Scraping
Premiers pas avec Python Web Scraping Practice
Laissez Heroku faire le traitement en arrière-plan avec Python
Un mémo contenant Python2.7 et Python3 dans CentOS
Carte des informations de location sur une carte avec python
Chase des applications actives sur Mac avec Python
[C] [python] Lire avec AquesTalk sous Linux