Ich habe ein Tool erstellt, um den Titel und die URL eines neuen Blogposts durch Scraping mit Python abzurufen. Es ist github-> https://github.com/cerven12/blog_post_getter
Als mein Freund mit dem Bloggen begann (neu gestartet?), Wollte ich versuchen, mein Gedächtnis zu verbessern und meine Schreibfähigkeiten durch das Posten von Blogs zu verbessern. Ich dachte, dass es aktiver wäre, von zwei Menschen angeregt zu werden, die miteinander konkurrieren und zusammenarbeiten, anstatt es alleine zu tun, also habe ich es als Teil davon gemacht.
Holen Sie sich den Titel und die URL des neu veröffentlichten Artikels. (Ich möchte es regelmäßig ausführen und über die LINE-API usw. benachrichtigen.)
Verwenden Sie die txt-Datei, die die URL der vorhandenen Beitragsliste enthält, und vergleichen Sie sie mit der URL der neuesten Beitragsliste. Ich versuche, Änderungen im Titel oder Inhalt nicht zu erkennen. (Weil es schwierig ist, eine Benachrichtigung mit der Aufschrift "Neu!" Zu erhalten, indem Sie einfach den Titel bearbeiten!) Die Ausnahme ist jedoch, wenn sich die URL beim Bearbeiten eines Artikels ändert (Gibt es ...?).
Ich weiß nichts über andere Websites, weil ich es so gemacht habe, dass es mit Qiita verwendet werden kann. Ich denke, dass es auf Seiten verwendet werden kann, auf denen HTML das folgende Format hat
<!--Das a-Tag enthält eine Klasse. Der Titel wird als Element des a-Tags geschrieben-->
<a class='articles' href='#'>Title</a>
Qiita-Benutzerseite: https://qiita.com/takuto_neko_like Hatena Blog-Benutzerseite: http://atc.hateblo.jp/about
import requests, bs4
def new_post_getter(url, selecter, txt):
'''
Artikeltitel und URL bs4_Element abrufen
1. Argument:URL der Seite mit der Beitragsliste
Zweites Argument:Von jedem Beitrag<a>Am am Kopf angebrachten Auswahlkopf.Mit
3. Argument:TXT-Pfad für die Aufnahme
'''
res = requests.get(url)
posts = bs4.BeautifulSoup(res.text, 'html.parser').select(selecter)
now_posts_url = [] #1 Liste der URLs der erfassten Artikelliste,Wird verwendet, um neue Beiträge durch Vergleich mit vorherigen Beitragsdaten zu identifizieren
now_posts_url_title_set = [] #Liste der URLs und Titel der erworbenen Artikelliste,
for post in posts:
#URL extrahieren
index_first = int(str(post).find('href=')) + 6
index_end = int(str(post).find('">'))
url = (str(post)[index_first : index_end])
#Titel extrahieren
index_first = int(str(post).find('">')) + 2
index_end = int(str(post).find('</a'))
title = (str(post)[index_first : index_end].replace('\u3000', ' ')) #Leerer Ersatz
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(',') #Von der Textdatei zum Listentyp
# differences :Beiträge, die gepostet wurden, aber nicht auf dem Listenbildschirm angezeigt werden+Neuer Beitrag
differences = list(set(now_posts_url) - set(old_post))
old_post_text.close()
#Überschreibe txt für die Aufnahme aller_Beiträge sind vergangene Beiträge+Neuer Beitrag
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
Seite der Artikelliste
, Auswahl, die an ein Tag jedes Artikels angehängt ist
, Geben Sie den Pfad der txt-Datei an, in der der Buchungsstatus gespeichert wird
als Argument
Versuchen Sie es mit
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)
Mit den oben genannten ...
Ergebnis
[['/takuto_neko_like/items/93b3751984e5e3fd3670', '[Fisch] Über die Sache, dass die Bewegung von Fischen zu langsam war ~ git Ärger ~'], ['/takuto_neko_like/items/14e92797fa2b23a64adb', '[Python] Was wird durch Mehrfachvererbung geerbt?']]
Sie können eine doppelte Liste von URLs und Titeln erhalten.
[[URL, Titel], [URL, Titel], [URL, Titel], .......]
Durch Drehen der Doppelliste mit einer for-Anweisung und Formatieren der Zeichenfolge ...
for url, title in my_posts:
print(f'{title} : {url}')
Gut lesbare Ausgabe ↓
Ausgabe
[Fisch] Über die Sache, dass die Bewegung von Fischen zu langsam war ~ git Ärger ~: /takuto_neko_like/items/93b3751984e5e3fd3670
[Python] Was wird durch Mehrfachvererbung geerbt?: /takuto_neko_like/items/14e92797fa2b23a64adb
Der Inhalt von neko.txt ist wie folgt.
/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
Enthält eine Liste von URLs. Versuchen Sie, den ersten und den letzten zu löschen ...
/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
Wenn du rennst ...
my_posts = new_post_getter(url, selecter, file)
print(my_posts)
Ergebnis ↓
[['/takuto_neko_like/items/c5791f267e0964e09d03', 'Es wurde ein Tool erstellt, mit dem neue Artikel dazu gebracht werden können, hart mit Freunden an Blog-Posts zu arbeiten'], ['/takuto_neko_like/items/93b3751984e5e3fd3670', '[Fisch] Über die Sache, dass die Bewegung von Fischen zu langsam war ~ git Ärger ~'], ['/takuto_neko_like/items/6cf9bade3d9515a724c0', '【Python】@Was sind Klassenmethoden und Dekorateure?']]
Holen Sie sich nur den gelöschten Betrag! ☺
Unten finden Sie eine Beschreibung des Codes.
<a>
Tags aller angezeigten Artikel von der Artikellistenseite ab1.Holen Sie sich das a-Tag aller angezeigten Artikel von der Artikellistenseite
import requests, bs4
def new_post_getter(url, selecter, txt):
'''
Artikeltitel und URL bs4_Element abrufen
1. Argument:URL der Seite mit der Beitragsliste
Zweites Argument:Von jedem Beitrag<a>Am am Kopf angebrachten Auswahlkopf.Mit
3. Argument:TXT-Pfad für die Aufnahme
'''
res = requests.get(url)
posts = bs4.BeautifulSoup(res.text, 'html.parser').select(selecter)
Wir werden hier zwei Bibliotheken von Drittanbietern verwenden.
Die Daten, die tatsächlich von dem oben genannten "★ Try using" erfasst wurden, sind der nächste weiße Rahmenteil
2.Holen Sie sich den Titel und die URL aus den erhaltenen Tags. Außerdem werden eine Reihe von URLs und Titeln separat extrahiert.
now_posts_url = [] #1 Liste der URLs der erfassten Artikelliste,Wird verwendet, um neue Beiträge durch Vergleich mit vorherigen Beitragsdaten zu identifizieren
now_posts_url_title_set = [] #Liste der URLs und Titel der erworbenen Artikelliste,
for post in posts:
#URL extrahieren
index_first = int(str(post).find('href=')) + 6
index_end = int(str(post).find('">'))
url = (str(post)[index_first : index_end])
#Titel extrahieren
index_first = int(str(post).find('">')) + 2
index_end = int(str(post).find('</a'))
title = (str(post)[index_first : index_end].replace('\u3000', ' ')) #Leerer Ersatz
now_posts_url.append(url)
now_posts_url_title_set.append(f"{url}>>>{title}")
Drehen Sie die erfassten <a>
Tag-Elemente mit einer for-Anweisung. Durch Angabe einer Zeichenfolge mit ".find ()" können Sie den Index der Startposition dieser Zeichenfolge ermitteln, sodass Sie den URL-Teil und den Titelteil erhalten, indem Sie die Zeichenfolge mit diesem Wert aufteilen.
now_posts_url
sind die Daten, die verwendet werden, um mit den bisher veröffentlichten Daten zu vergleichen und die Differenz zu extrahieren (ausgenommen Artikel, die aufgrund der Seitennation usw. vom Listenbildschirm verschwunden sind).
Dieses Mal erkennen wir Neuankömmlinge anhand einer URL, die sich auch bei Aktualisierung des Artikels nicht ändert. Um den Titel und die URL später auszugeben, speichern Sie jetzt den Satz "URL + Titel". Ich will. Verwenden Sie daher "now_posts_url", um die Differenz zu ermitteln, und extrahieren Sie später nur die Daten, die die Differenz-URL enthalten, aus "now_posts_url_title_set".
3.Liste der vorhandenen Beiträge(txt)Verwenden von, 2. Vergleichen Sie mit der URL in. Extrahieren Sie den Unterschied.
old_post_text = open(txt)
old_post = old_post_text.read().split(',') #Von der Textdatei zum Listentyp
# differences :Beiträge, die gepostet wurden, aber nicht auf dem Listenbildschirm angezeigt werden+Neuer Beitrag
differences = list(set(now_posts_url) - set(old_post))
old_post_text.close()
Ich möchte mit der txt-Datei vergleichen, in der die bisherigen Post-Datensätze gespeichert sind, und den Unterschied aus der zuletzt neu erworbenen Post-Liste extrahieren. Es ist ein Unterschied. Im Ben-Diagramm ist es wie folgt A ist eine Liste vergangener Beiträge B ist die neueste Beitragsliste Und der schattierte Bereich ist der Unterschied, der ein völlig neuer Beitrag ist.
Set-Operationen können einfach ausgeführt werden, indem das Berechnungsziel auf ein Set-Typ-Objekt gesetzt wird.
Dieses Mal wird die in der txt-Datei aufgezeichnete Zeichenkette vom Listentyp ([URL1, URL2, URL3]
) mit split ()
in den Listentyp konvertiert.
Die Differenz wird beim Konvertieren in den festgelegten Typ zusammen mit der neuesten Beitragsliste in 2 berechnet.
Überschreiben Sie txt mit der URL des neuen Beitrags und dem vorhandenen Beitragsdatensatz in einem
#Überschreibe txt für die Aufnahme aller_Beiträge sind vergangene Beiträge+Neuer Beitrag
all_posts = ",".join(old_post + differences)
f = open(txt, mode='w')
f.writelines(all_posts)
f.close()
Die txt-Datei sollte auch mit den neuesten Informationen aktualisiert werden, damit sie beim nächsten Mal verwendet werden kann. Überschreiben Sie die txt-Datei, indem Sie den Unterschied (neuer Beitrag) zu den vorherigen Beiträgen hinzufügen.
Formatieren Sie den neuen Titel und die neue URL des Beitrags
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
Aus den Daten der Zeichenfolge "URL >>> Titel", die im Voraus in 2. erhalten wurden, werden nur die Daten erhalten, die die URL (Zeichenfolge) enthalten, die der Differenz entspricht.
Da es sich um eine Zeichenfolge handelt, ist es in Ordnung, wenn dasselbe Zeichen mit dem Operator "in" in der Zeichenfolge enthalten ist. Dadurch konnte ich die URL und den Titel des neuen Artikels abrufen.
~~ Ich möchte regelmäßig Chats mit Freunden benachrichtigen können. später. ~~
Nachtrag 2020/03/09
Ich habe Line Notify verwendet.
def send_line_notify(posts, token):
'''
# new_post_Nehmen Sie den Rückgabewert von Getter als 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,)
Auf diese Weise verwenden
token = '########'
neko_post = new_post_getter(neko_url, neko_selecter, neko_txt)
send_line_notify(neko_post, token)
Wenn Sie den Rückgabewert und das Token der Funktion "new_post_getter" als Argumente angeben, wird es an "LINE Notify" gesendet. Ich habe auf [hier] verwiesen (https://qiita.com/moriita/items/5b199ac6b14ceaa4f7c9).
Ich möchte jede Minute mit ~~ Python überall laufen. später. ~~
2020/03/09 Kopieren Sie jede Datei an eine beliebige Stelle nach Python und erstellen Sie .sh wie folgt
In der Lage sein, die virtuelle Umgebung zu cronen
source /home/<Konto>/blog_post_notice/venv/bin/activate
python3 /home/<Konto>/blog_post_notice/send.py ##
Wenn ich dann versuche, .sh auszuführen, bevor ich cron einrichte ...
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')))
Nach einer Untersuchung scheint Python überall nur auf externe Websites zugreifen zu können, die Whitelist entsprechen, um den unbefugten Zugriff auf kostenlose Konten zu verhindern. Also habe ich Python überall aufgegeben ...
Ich habe versucht, in Heroku zu implementieren. Da Sie jedoch keine Dateien in Heroku speichern können, können Sie die txt-Datei nicht in demselben Verzeichnis überschreiben wie bei der Verarbeitung in Python wie diesmal. Ich habe versucht, die Datei zu aktualisieren, indem ich die Google Drive- und Dropbox-APIs von Python aus manipuliert habe. Es scheint, dass ich den Dateinamen und die Metadaten abrufen und eine neue Datei hinzufügen kann, aber ich wusste nicht, wie ich den Inhalt der Datei abrufen kann.
Daher werde ich dieses Mal cron auf meinem PC einrichten und es regelmäßig ausführen.
Als crontab -e
...
Versuchen Sie es vorerst jede Minute
0 * * * * sh /Users/Nutzername/dir1/post_notice/notice.sh
Recommended Posts