J'ai créé un outil pour obtenir le titre et l'URL d'un nouvel article de blog en grattant avec python. C'est github-> https://github.com/cerven12/blog_post_getter
Quand mon ami a commencé (redémarré?) Bloguer, je voulais essayer de réparer ma mémoire et d'améliorer mes compétences en rédaction en publiant des blogs. Je pensais qu'il serait plus actif d'être stimulé par deux personnes en compétition et coopérant l'une avec l'autre plutôt que de le faire seul, alors j'ai fait partie de cela.
Obtenez le titre et l'URL de l'article récemment publié. (Je voudrais l'exécuter régulièrement et le notifier par LINE API etc.)
Utilisez le fichier txt qui contient l'URL de la liste de publications existante et comparez-la avec l'URL de la dernière liste de publications. J'essaie de ne pas détecter les changements dans le titre ou le contenu. (Parce qu'il est difficile d'obtenir une notification disant "Nouveau!" Juste en modifiant le titre!) Cependant, l'exception concerne les articles dont l'URL change lors de l'édition (Y a-t-il ...?).
Je ne connais pas d'autres sites car je l'ai fait pour qu'il puisse être utilisé avec Qiita. Je pense qu'il peut être utilisé sur des pages où html a le format suivant
<!--Il y a une classe dans la balise a. Le titre est écrit comme un élément de la balise a-->
<a class='articles' href='#'>Title</a>
Page utilisateur de Qiita: https://qiita.com/takuto_neko_like Page utilisateur du blog Hatena: http://atc.hateblo.jp/about
<a>
de chaque article.
import requests, bs4
def new_post_getter(url, selecter, txt):
'''
Titre de l'article et URL bs4_Obtenir l'élément
1er argument:URL de la page avec la liste des articles
Deuxième argument:De chaque poste<a>Au niveau de la tête de sélection attachée à l'étiquette.Avec
3e argument:Chemin Txt pour l'enregistrement
'''
res = requests.get(url)
posts = bs4.BeautifulSoup(res.text, 'html.parser').select(selecter)
now_posts_url = [] #1 Liste des URL de la liste d'articles acquis,Utilisé pour identifier les nouveaux articles en les comparant aux données des articles précédents
now_posts_url_title_set = [] #Liste des URL et des titres de la liste d'articles acquis,
for post in posts:
#Extraire l'URL
index_first = int(str(post).find('href=')) + 6
index_end = int(str(post).find('">'))
url = (str(post)[index_first : index_end])
#Extrait du titre
index_first = int(str(post).find('">')) + 2
index_end = int(str(post).find('</a'))
title = (str(post)[index_first : index_end].replace('\u3000', ' ')) #Remplacement du blanc
now_posts_url.append(url)
now_posts_url_title_set.append(f"{url}>>>{title}")
old_post_text = open(txt)
old_post = old_post_text.read().split(',') #Du fichier texte au type de liste
# differences :Messages qui ont été publiés mais qui ne sont pas affichés sur l'écran de liste+Nouveau poste
differences = list(set(now_posts_url) - set(old_post))
old_post_text.close()
#Écraser le txt pour tout enregistrer_les messages sont des messages passés+Nouveau poste
all_posts = ",".join(old_post + differences)
f = open(txt, mode='w')
f.writelines(all_posts)
f.close()
new_post_info = []
for new in now_posts_url_title_set:
for incremental in differences:
if incremental in new:
new_post_info.append(new.split(">>>"))
return new_post_info
Page de liste d'articles
, Sélecteur attaché à une balise de chaque article
, Spécifiez le chemin du fichier txt qui enregistre l'état de publication
comme argument
Essayez d'utiliser
url = 'https://qiita.com/takuto_neko_like'
selecter = '.u-link-no-underline'
file = 'neko.txt'
my_posts = new_post_getter(url, selecter, file)
print(my_posts)
En faisant ce qui précède ...
résultat
[['/takuto_neko_like/items/93b3751984e5e3fd3670', '[Poisson] À propos du fait que le mouvement des poissons était trop lent ~ git trouble ~'], ['/takuto_neko_like/items/14e92797fa2b23a64adb', '[Python] Qu'est-ce qui est hérité par l'héritage multiple?']]
Vous pouvez obtenir une double liste d'URL et de titres.
[[URL, titre], [URL, titre], [URL, titre], .......]
En tournant la liste double avec une instruction for et en formatant la chaîne de caractères ...
for url, title in my_posts:
print(f'{title} : {url}')
Sortie facile à lire ↓
production
[Poisson] À propos du fait que le mouvement des poissons était trop lent ~ git trouble ~: /takuto_neko_like/items/93b3751984e5e3fd3670
[Python] Qu'est-ce qui est hérité par l'héritage multiple?: /takuto_neko_like/items/14e92797fa2b23a64adb
Le contenu de neko.txt est comme ça.
/takuto_neko_like/items/93b3751984e5e3fd3670,/takuto_neko_like/items/14e92797fa2b23a64adb,/takuto_neko_like/items/bb8d0957347636b5bf4f,/takuto_neko_like/items/62aeb4271614f6f0347f,/takuto_neko_like/items/c9c80ff453d0c4fad239,/takuto_neko_like/items/aed9dd5619d8457d4894,/takuto_neko_like/items/6cf9bade3d9515a724c0
Contient une liste d'URL. Essayez de supprimer le premier et le dernier ...
/takuto_neko_like/items/14e92797fa2b23a64adb,/takuto_neko_like/items/bb8d0957347636b5bf4f,/takuto_neko_like/items/62aeb4271614f6f0347f,/takuto_neko_like/items/c9c80ff453d0c4fad239,/takuto_neko_like/items/aed9dd5619d8457d4894
Quand tu cours ...
my_posts = new_post_getter(url, selecter, file)
print(my_posts)
Résultat ↓
[['/takuto_neko_like/items/c5791f267e0964e09d03', 'Création d'un outil pour que de nouveaux articles travaillent dur avec des amis sur des articles de blog'], ['/takuto_neko_like/items/93b3751984e5e3fd3670', '[Poisson] À propos du fait que le mouvement des poissons était trop lent ~ git trouble ~'], ['/takuto_neko_like/items/6cf9bade3d9515a724c0', '【Python】@Que sont les méthodes de classe et les décorateurs?']]
Obtenez uniquement le montant supprimé! ☺
Vous trouverez ci-dessous une description du code.
<a>
de tous les articles affichés à partir de la page de liste d'articles1.Obtenir la balise a de tous les articles affichés à partir de la page de liste d'articles
import requests, bs4
def new_post_getter(url, selecter, txt):
'''
Titre de l'article et URL bs4_Obtenir l'élément
1er argument:URL de la page avec la liste des articles
Deuxième argument:De chaque poste<a>Au niveau de la tête de sélection attachée à l'étiquette.Avec
3e argument:Chemin Txt pour l'enregistrement
'''
res = requests.get(url)
posts = bs4.BeautifulSoup(res.text, 'html.parser').select(selecter)
Nous utiliserons ici deux bibliothèques tierces.
.text
. Beautiful Soup in 2. utilise le texte HTML renvoyé comme réponse..select
pour spécifier un sélecteur spécifique. Cela vous donnera plusieurs éléments pour ce sélecteur.Les données réellement acquises par le "★ Essayer d'utiliser" ci-dessus sont la prochaine partie du cadre blanc
2.Obtenez le titre et l'URL des balises a obtenues. En outre, un ensemble d'URL et de titre est extrait séparément.
now_posts_url = [] #1 Liste des URL de la liste d'articles acquis,Utilisé pour identifier les nouveaux articles en les comparant aux données des articles précédents
now_posts_url_title_set = [] #Liste des URL et des titres de la liste d'articles acquis,
for post in posts:
#Extraire l'URL
index_first = int(str(post).find('href=')) + 6
index_end = int(str(post).find('">'))
url = (str(post)[index_first : index_end])
#Extrait du titre
index_first = int(str(post).find('">')) + 2
index_end = int(str(post).find('</a'))
title = (str(post)[index_first : index_end].replace('\u3000', ' ')) #Remplacement du blanc
now_posts_url.append(url)
now_posts_url_title_set.append(f"{url}>>>{title}")
Tournez les éléments de balise acquis <a>
avec une instruction for. En spécifiant une chaîne de caractères avec .find ()
, vous pouvez trouver l'index de la position de départ de cette chaîne de caractères, donc en découpant la chaîne de caractères avec cette valeur, vous pouvez obtenir la partie URL et la partie titre.
now_posts_url
est les données utilisées pour comparer avec les données publiées jusqu'à présent et extraire la différence (à l'exclusion des articles qui ont disparu de l'écran de liste en raison de la nation de la page, etc.).
Cette fois, nous détecterons les nouveaux arrivants en utilisant une URL qui ne changera pas même si l'article est mis à jour, mais afin de sortir le titre et l'URL plus tard, enregistrez maintenant l'ensemble de ʻURL + titre. Je veux. Par conséquent, utilisez
now_posts_url pour obtenir la différence, et extrayez plus tard uniquement les données contenant l'URL de différence de
now_posts_url_title_set`.
3.Liste des messages existants(txt)Utilisation, 2. Comparez avec l'URL obtenue dans. Extrayez la différence.
old_post_text = open(txt)
old_post = old_post_text.read().split(',') #Du fichier texte au type de liste
# differences :Messages qui ont été publiés mais qui ne sont pas affichés sur l'écran de liste+Nouveau poste
differences = list(set(now_posts_url) - set(old_post))
old_post_text.close()
Je veux comparer avec le fichier txt où les enregistrements de publication jusqu'à présent sont enregistrés et extraire la différence de la dernière liste de publications nouvellement acquise. C'est une différence. Dans le diagramme de Ben, c'est comme suit A est une liste de messages passés B est la dernière liste de messages Et la zone ombrée fait la différence, qui est un tout nouveau message.
Les opérations d'ensemble peuvent être facilement effectuées en définissant la cible de calcul sur un objet de type d'ensemble.
Cette fois, la chaîne de caractères de type liste ([URL1, URL2, URL3]
) enregistrée dans le fichier txt est convertie en type liste avec split ()
.
La différence est calculée lors de la conversion vers le type d'ensemble avec la dernière liste de messages obtenue en 2.
Remplacez le txt par l'URL du nouveau message et de l'enregistrement de l'article existant en un
#Écraser le txt pour tout enregistrer_les messages sont des messages passés+Nouveau poste
all_posts = ",".join(old_post + differences)
f = open(txt, mode='w')
f.writelines(all_posts)
f.close()
Le fichier txt doit également être mis à jour avec les dernières informations afin de pouvoir être utilisé la prochaine fois. Remplacez le fichier txt en ajoutant la différence (nouvel article) aux articles précédents.
Mettre en forme le nouveau titre et l'URL du message
new_post_info = []
for new in now_posts_url_title_set:
for incremental in differences:
if incremental in new:
new_post_info.append(new.split(">>>"))
return new_post_info
A partir des données de la chaîne de caractères "URL >>> Titre" obtenues au préalable en 2., seules les données contenant l'URL (chaîne de caractères) correspondant à la différence sont obtenues.
Puisqu'il s'agit d'une chaîne de caractères, c'est OK si le même caractère est inclus dans la chaîne de caractères avec l'opérateur ʻin`. Cela m'a permis d'obtenir l'URL et le titre du nouvel article.
~~ Je veux être en mesure de notifier régulièrement les discussions avec des amis. plus tard. ~~
2020/03/09 postscript
J'ai utilisé la notification de ligne.
def send_line_notify(posts, token):
'''
# new_post_Prenez la valeur de retour de getter comme argument
'''
notice_url = "https://notify-api.line.me/api/notify"
headers = {"Authorization" : "Bearer "+ token}
for url, title in posts:
if 'http' not in url:
url = 'https://qiita.com/' + url
message = f'{title}:{url}'
payload = {'message': message}
r = requests.post(notice_url, headers=headers, params=payload,)
Utiliser de cette manière
token = '########'
neko_post = new_post_getter(neko_url, neko_selecter, neko_txt)
send_line_notify(neko_post, token)
Si vous spécifiez la valeur de retour et le jeton de la fonction new_post_getter
comme arguments, il sera envoyé à LINE Notify
.
J'ai fait référence à ici.
Je veux courir chaque minute en utilisant ~~ python n'importe où. plus tard. ~~
2020/03/09 Copiez chaque fichier en python n'importe où et créez .sh comme ci-dessous
Pour pouvoir croner l'environnement virtuel
source /home/<Compte>/blog_post_notice/venv/bin/activate
python3 /home/<Compte>/blog_post_notice/send.py ##
Ensuite, quand j'essaye d'exécuter .sh avant de configurer cron ...
Error
requests.exceptions.ProxyError: HTTPSConnectionPool(host='qiita.com', port=443): Max retries exceeded with url: /takuto_neko_like (Caused by ProxyError('Canno
t connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden')))
Après enquête, il semble que Python n'importe où ne puisse accéder qu'aux sites externes qui correspondent à Whitelist afin d'empêcher l'accès non autorisé aux comptes gratuits. Alors j'ai abandonné le python n'importe où ...
J'ai essayé de me déployer sur Heroku. Cependant, comme il n'est pas possible d'enregistrer des fichiers dans Heroku, il n'est pas possible d'écraser le fichier txt dans le même répertoire avec le traitement en python comme cette fois. J'ai essayé de mettre à jour le fichier en manipulant les API Google Drive et Dropbox à partir de python. Il semble que je puisse obtenir le nom du fichier et les métadonnées, et ajouter un nouveau fichier, mais je ne savais pas comment obtenir le contenu du fichier.
Par conséquent, cette fois, je vais installer cron sur mon PC et l'exécuter régulièrement.
Comme crontab -e
...
Pour le moment, essayez de l'exécuter toutes les minutes
0 * * * * sh /Users/Nom d'utilisateur/dir1/post_notice/notice.sh
Recommended Posts