Ich habe mit Docker eine Umgebung erstellt, um Qiita-Trendinformationen zu speichern. Wenn Sie den Container starten, wird der Scraping-Prozess grundsätzlich jeden Tag von selbst ausgeführt und die in JSON konvertierten Trendinformationen werden gespeichert. Dieser Artikel wird folgenden Personen empfohlen.
――Ich möchte den Trend von Qiita analysieren ――Ich möchte Python ein wenig lernen
--author (Liste der Trendautoren) --list (Liste der Trendartikel --tag (Liste der Tags, die an Trendartikel angehängt sind
Der Inhalt des tatsächlich gespeicherten JSON lautet wie folgt.
author
: Holen Sie sich Trendautoren für QiitaListen Sie die Benutzernamen des Autors auf.
[
"uhyo",
"suin",
"Yz_4230",
"atskimura",
"pineappledreams",
"Amanokawa",
"k_shibusawa",
"minakawa-daiki",
"morry_48",
"c60evaporator",
"takuya_tsurumi",
"TomoEndo",
"yhatt",
"CEML",
"moritalous",
"svfreerider",
"daisukeoda",
"karaage0703",
"tommy19970714",
"tyru",
"galileo15640215",
"keitah",
"mocapapa",
"akeome",
"ssssssssok1",
"yuno_miyako",
"katzueno",
"cometscome_phys",
"mpyw",
"akane_kato"
]
list
: Ruft eine Liste der Artikel ab, die in Qiita enthalten sindDie folgenden Informationen werden ausgegeben.
--Artikel-UUID (Artikel-ID) --Artikelüberschrift --Artikel-URL
[
{
"article_id":"e66cbca2f582e81d5b16",
"article_title":"Let'Proxyserver, der Webseiten mit s Encrypt blockiert",
"article_url":"https://qiita.com/uhyo/items/e66cbca2f582e81d5b16",
"author_name":"uhyo",
"likes":66,
"tag_list":[
{
"tag_link":"/tags/javascript",
"tag_name":"JavaScript"
},
{
"tag_link":"/tags/node.js",
"tag_name":"Node.js"
},
{
"tag_link":"/tags/proxy",
"tag_name":"proxy"
},
{
"tag_link":"/tags/https",
"tag_name":"HTTPS"
},
{
"tag_link":"/tags/letsencrypt",
"tag_name":"letsencrypt"
}
]
},
{
"article_id":"83ebaf96caa2c13c8b2f",
"article_title":"Erstellen Sie einen MacOS-Bildschirmschoner mit HTML / CSS / JS(Keine schnellen Fähigkeiten erforderlich)",
"article_url":"https://qiita.com/suin/items/83ebaf96caa2c13c8b2f",
"author_name":"suin",
"likes":60,
"tag_list":[
{
"tag_link":"/tags/html",
"tag_name":"HTML"
},
{
"tag_link":"/tags/css",
"tag_name":"CSS"
},
{
"tag_link":"/tags/javascript",
"tag_name":"JavaScript"
},
{
"tag_link":"/tags/macos",
"tag_name":"macos"
}
]
}
]
Qiitas Trend wird jeden Tag zweimal täglich um 5/17 Uhr aktualisiert, aber da sich die Artikel nicht so sehr ändern, werde ich ihn nur einmal am Tag ausführen.
tag
: Die Tags werden an Artikel angehängt, die in Qiita enthalten sind[
{
"tag_link":"/tags/python",
"tag_name":"Python"
},
{
"tag_link":"/tags/r",
"tag_name":"R"
},
{
"tag_link":"/tags/%e6%a9%9f%e6%a2%b0%e5%ad%a6%e7%bf%92",
"tag_name":"Maschinelles Lernen"
}
]
Die Tags werden auch in der obigen Artikelliste erfasst. Da es sich jedoch um Tags handelt, die mit einem Artikel verknüpft sind, werden sie dupliziert, wenn dasselbe Tag an verschiedene Artikel angehängt wird. Aus diesem Grund haben wir beschlossen, doppelte Tags wegzulassen und nur die Tags mit Trends in einer Liste zu speichern.
Wir werden eine einfache Docker-Umgebung erstellen. Die Verzeichnisstruktur sieht wie folgt aus.
├── batch
│ └── py
│ └── article.py
├── docker
│ └── python
│ ├── Dockerfile
│ ├── etc
│ │ └── cron.d
│ │ └── qiita
│ └── requirements.txt
├── docker-compose.yml
└── mnt
└── json
├── author
├── list
└── tag
batch
directory
Ich habe eine Python-Datei.
Diese Datei ist die eigentliche Datei, die abgekratzt werden soll.
docker
directory
Hier finden Sie, was Sie im Container benötigen, oder die tatsächlichen Cron-Einstellungen
mnt
directory
Ich habe ein Verzeichnis auf dem Host gemountet und eine JSON-Datei wird hier als Ergebnis des Scrapings generiert
Batch-Verzeichnis
)Der Inhalt der realen Datei "article.py" im Stapelverzeichnis. Ich habe in der Vergangenheit einen solchen Artikel geschrieben, daher werde ich dort die detaillierte Methode erläutern. >> Holen Sie sich Qiita-Trends (Ranking) und senden Sie sie an Slack In diesem Artikel werde ich nur das Programm verwenden.
Es gibt zwei Unterschiede zum Programm im obigen Artikel. Ich möchte nur eine Liste von Artikeln! Ich denke, dass der obige Artikel für Menschen genug ist.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import json
import datetime
import os
def get_article_tags(detail_url):
tag_list = []
res = requests.get(detail_url, headers=headers)
#Behandeln Sie HTML mit schöner Suppe
soup = BeautifulSoup(res.text, "html.parser")
tags = soup.find_all(class_="it-Tags_item")
for tag in tags:
tag_name = tag.get_text()
tag_link = tag.get('href')
tag_list.append({
'tag_name' : tag_name,
'tag_link': tag_link
})
return tag_list
def write_json(json_list, path):
with open(path, 'w') as f:
f.write(json.dumps(json_list, ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ':')))
def mkdir(path):
os.makedirs(path, exist_ok=True)
def get_unique_list(seq):
seen = []
return [x for x in seq if x not in seen and not seen.append(x)]
def get_unique_tag(tag_lists):
tags = []
for v in tag_lists:
for i in v:
tags.append(i)
return tags
try:
# Root URL
url = "https://qiita.com/"
headers = {
"User-Agent" : "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
today_date = datetime.datetime.now().date()
items = []
item_json = []
result = []
res = requests.get(url, headers=headers)
#Behandeln Sie HTML mit schöner Suppe
soup = BeautifulSoup(res.text, "html.parser")
try:
main_items = soup.find(class_="p-home_main")
for main_items in soup.find_all():
if "data-hyperapp-props" in main_items.attrs:
item_json.append(main_items["data-hyperapp-props"])
items = json.loads(item_json[1])
except:
raise Exception("Not Found Json Dom Info")
if 'edges' not in items['trend']:
raise Exception("The expected list does not exist")
try:
item_detail_list = []
tags_list = []
author_list = []
for edges in items['trend']['edges']:
uuid = edges['node']['uuid']
title = edges['node']['title']
likes = edges['node']['likesCount']
article_url = url + edges['node']['author']['urlName'] + '/items/' + uuid
author_name = edges['node']['author']['urlName']
create_at = datetime.datetime.now().date()
tag_list = get_article_tags(article_url)
item = {
'article_title' : title,
'article_url' : article_url,
'article_id' : edges['node']['uuid'],
'likes' : likes,
'uuid' : uuid,
'author_name' : author_name,
'tag_list' : tag_list,
}
item_detail_list.append(item)
tags_list.append(tag_list)
author_list.append(author_name)
mkdir('/mnt/json/list/')
mkdir('/mnt/json/tag/')
mkdir('/mnt/json/author/')
#Tags eindeutig machen
tags_list = get_unique_tag(tags_list)
#Exportieren Sie die JSON-Datei
write_json(item_detail_list, f"/mnt/json/list/{today_date}.json")
write_json(tags_list, f"/mnt/json/tag/{today_date}.json")
write_json(author_list, f"/mnt/json/author/{today_date}.json")
except:
raise Exception("Can't Create Json")
except Exception as e:
#Fehler beim Erstellen der JSON-Datei
mkdir('/mnt/log/')
with open(f'/mnt/log/{today_date}', 'w') as f:
f.write(e)
Erstellen Sie als Nächstes eine Umgebung, um die oben genannten Dateien auszuführen.
Hier ist es keine große Sache. Verzeichnisse und Bereitstellungen auf Ihrem PC mit Volumes.
version: "3"
qiita_batch:
container_name: "qiita_batch"
build:
context: ./docker/python
tty: true
volumes:
- ./batch:/usr/src/app
- ./mnt:/mnt
Dockerfile Verzeih mir, dass ich schmutzig bin ... nur eine kurze Erklärung ↓
Wenn Sie cron in der angegebenen japanischen Zeit ausführen möchten, müssen Sie unbedingt die Zeitzone festlegen. Ich habe etwas durcheinander gebracht und mich schließlich der japanischen Zeit zugewandt, aber es muss einen besseren Weg geben ...
Die Cron-Einstellungen werden in etc / cron.d / qiita zusammengestellt und später in crontab geschrieben. Ich frage mich, ob dies besser ist, weil es einfacher zu verwalten sein wird. Wenn Sie einen Fehler machen, rufen Sie nicht den Befehl "crontab -r" auf ...! !!
FROM python:3
ARG project_dir=/usr/src/app
WORKDIR $project_dir
ADD requirements.txt $project_dir/py/
ADD /etc/cron.d/qiita /etc/cron.d/
ENV TZ=Asia/Tokyo
RUN apt-get update && \
apt-get install -y cron less vim tzdata && \
rm -rf /var/lib/apt/lists/* && \
echo "${TZ}" > /etc/timezone && \
rm /etc/localtime && \
ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
chmod 0744 /etc/cron.d/* && \
touch /var/log/cron.log && \
crontab /etc/cron.d/qiita && \
pip install --upgrade pip && \
pip install -r $project_dir/py/requirements.txt
CMD ["cron", "-f"]
Da request.txt nur die Ausgabe dessen ist, was ich auf meinem Macbook Pro verwendet habe, enthält es eine Menge Dinge. Bitte kratzen Sie, was Sie nicht brauchen. Alles was Sie brauchen ist "schöne Suppe4", "Anfragen" und "Json". Ich habe nicht genug Die Leute bewegen sich und nicht genug Pip installieren! !!
appdirs==1.4.3
beautifulsoup4==4.8.1
bs4==0.0.1
certifi==2019.9.11
chardet==3.0.4
Click==7.0
filelock==3.0.12
get==2019.4.13
gunicorn==20.0.4
idna==2.8
importlib-metadata==1.5.0
importlib-resources==1.0.2
itsdangerous==1.1.0
Jinja2==2.11.1
MarkupSafe==1.1.1
post==2019.4.13
public==2019.4.13
query-string==2019.4.13
request==2019.4.13
requests==2.22.0
six==1.14.0
soupsieve==1.9.5
urllib3==1.25.7
virtualenv==20.0.1
Werkzeug==1.0.0
zipp==2.2.0
Der Inhalt von / etc / cron.d / qiita
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=ja_JP.UTF-8
# Create Qiita JSON (every day AM:10:00)
0 10 * * * python /usr/src/app/py/article.py >> /var/log/cron.log 2>&1
So was! Wenn Sie es danach mit "docker-compose up -d" tun, wird es gestartet. Wenn Sie es also in Ruhe lassen, wird es zum Scraping an Qiita gesendet und eine JSON-Datei erstellt. Empfohlen, da dies in einer einfachen Docker-Umgebung möglich ist!
Recommended Posts