ΠΠΎΠ±ΡΡΠΉ Π΄Π΅Π½Ρ. ΠΡΠΎΡΠ»ΠΎ ΡΠΆΠ΅ 2 Π³ΠΎΠ΄Π° Ρ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ
ΠΠΎΠ³Π΄Π° Ρ Π·Π°Ρ ΠΎΡΠ΅Π» ΠΈΠΌΠ΅ΡΡ Ρ ΡΠ΅Π±Ρ ΠΊΠΎΠΏΠΈΡ Ρ Π°Π±ΡΠ°, Ρ ΡΠ΅ΡΠΈΠ» Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΠ°ΡΡΠ΅Ρ, ΠΊΠΎΡΠΎΡΡΠΉ Π±Ρ ΡΠΎΡ ΡΠ°Π½ΠΈΠ» Π²Π΅ΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π°Π²ΡΠΎΡΠΎΠ² Π² Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ . ΠΠ°ΠΊ ΡΡΠΎ Π²ΡΡΠ»ΠΎ ΠΈ Ρ ΠΊΠ°ΠΊΠΈΠΌΠΈ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ Ρ Π²ΡΡΡΠ΅ΡΠΈΠ»ΡΡ β ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ ΠΏΠΎΠ΄ ΠΊΠ°ΡΠΎΠΌ.
TL;DR β
ΠΠ΅ΡΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ ΠΏΠ°ΡΡΠ΅ΡΠ°. ΠΠ΄ΠΈΠ½ ΠΏΠΎΡΠΎΠΊ, ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌ
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π°, Ρ ΡΠ΅ΡΠΈΠ» ΡΠ΄Π΅Π»Π°ΡΡ ΠΏΡΠΎΡΠΎΡΠΈΠΏ ΡΠΊΡΠΈΠΏΡΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π±Ρ ΡΡΠ°Π·Ρ ΠΏΡΠΈ ΡΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠΈ ΡΡΠ°ΡΡΡ ΠΏΠ°ΡΡΠΈΠ»Π°ΡΡ ΠΈ ΠΏΠΎΠΌΠ΅ΡΠ°Π»Π°ΡΡ Π² Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ . ΠΠ΅Π΄ΠΎΠ»Π³ΠΎ Π΄ΡΠΌΠ°Π², ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π» sqlite3, Ρ.ΠΊ. ΡΡΠΎ Π±ΡΠ»ΠΎ ΠΌΠ΅Π½Π΅Π΅ ΡΡΡΠ΄ΠΎΠ·Π°ΡΡΠ°ΡΠ½ΠΎ: Π½Π΅ Π½ΡΠΆΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ, ΡΠΎΠ·Π΄Π°Π»-ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π»-ΡΠ΄Π°Π»ΠΈΠ» ΠΈ Π²ΡΠ΅ Π² ΡΠ°ΠΊΠΎΠΌ Π΄ΡΡ Π΅.
one_thread.py
from bs4 import BeautifulSoup
import sqlite3
import requests
from datetime import datetime
def main(min, max):
conn = sqlite3.connect('habr.db')
c = conn.cursor()
c.execute('PRAGMA encoding = "UTF-8"')
c.execute("CREATE TABLE IF NOT EXISTS habr(id INT, author VARCHAR(255), title VARCHAR(255), content TEXT, tags TEXT)")
start_time = datetime.now()
c.execute("begin")
for i in range(min, max):
url = "https://m.habr.com/post/{}".format(i)
try:
r = requests.get(url)
except:
with open("req_errors.txt") as file:
file.write(i)
continue
if(r.status_code != 200):
print("{} - {}".format(i, r.status_code))
continue
html_doc = r.text
soup = BeautifulSoup(html_doc, 'html.parser')
try:
author = soup.find(class_="tm-user-info__username").get_text()
content = soup.find(id="post-content-body")
content = str(content)
title = soup.find(class_="tm-article-title__text").get_text()
tags = soup.find(class_="tm-article__tags").get_text()
tags = tags[5:]
except:
author,title,tags = "Error", "Error {}".format(r.status_code), "Error"
content = "ΠΡΠΈ ΠΏΠ°ΡΡΠΈΠ½Π³Π΅ ΡΡΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ°."
c.execute('INSERT INTO habr VALUES (?, ?, ?, ?, ?)', (i, author, title, content, tags))
print(i)
c.execute("commit")
print(datetime.now() - start_time)
main(1, 490406)
ΠΡΡ ΠΏΠΎ ΠΊΠ»Π°ΡΡΠΈΠΊΠ΅ β ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Beautiful Soup, requests ΠΈ Π±ΡΡΡΡΡΠΉ ΠΏΡΠΎΡΠΎΡΠΈΠΏ Π³ΠΎΡΠΎΠ². ΠΠΎΡ ΡΠΎΠ»ΡΠΊΠΎβ¦
-
Π‘ΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΡΡΡΠ°Π½ΠΈΡΡ ΠΈΠ΄Π΅Ρ Π² ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡΠΎΠΊ
-
ΠΡΠ»ΠΈ ΠΎΠ±ΠΎΡΠ²Π°ΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΠΊΡΠΈΠΏΡΠ°, ΡΠΎ Π²ΡΡ Π±Π°Π·Π° ΡΠΉΠ΄Π΅Ρ Π² Π½ΠΈΠΊΡΠ΄Π°. ΠΠ΅Π΄Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΌΠΈΡΠ° ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠ»Π΅ Π²ΡΠ΅Π³ΠΎ ΠΏΠ°ΡΡΠΈΠ½Π³Π°.
ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΊΡΠ΅ΠΏΠ»ΡΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² Π±Π°Π·Π΅ ΠΏΠΎΡΠ»Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π²ΡΡΠ°Π²ΠΊΠΈ, Π½ΠΎ ΡΠΎΠ³Π΄Π° ΠΈ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠΊΡΠΈΠΏΡΠ° ΡΠ²Π΅Π»ΠΈΡΠΈΡΡΡ Π² ΡΠ°Π·Ρ. -
ΠΠ°ΡΡΠΈΠ½Π³ ΠΏΠ΅ΡΠ²ΡΡ 100 000 ΡΡΠ°ΡΠ΅ΠΉ Ρ ΠΌΠ΅Π½Ρ Π·Π°Π½ΡΠ» 8 ΡΠ°ΡΠΎΠ².
ΠΠ°Π»ΡΡΠ΅ Ρ Π½Π°Ρ
ΠΎΠΆΡ ΡΡΠ°ΡΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ
- ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΡΡΠΈ ΡΡΠΊΠΎΡΡΠ΅Ρ ΡΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ Π² ΡΠ°Π·Ρ.
- ΠΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π½Π΅ ΠΏΠΎΠ»Π½ΡΡ Π²Π΅ΡΡΠΈΡ Ρ
Π°Π±ΡΠ°, Π° Π΅Π³ΠΎ ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΡΡ Π²Π΅ΡΡΠΈΡ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ ΡΡΠ°ΡΡΡ cointegrated Π² Π΄Π΅ΡΠΊΡΠΎΠΏΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Π²Π΅ΡΠΈΡ 378 ΠΠ±, ΡΠΎ Π² ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΠΎΠΉ ΡΠΆΠ΅ 126 ΠΠ±.
ΠΡΠΎΡΠ°Ρ Π²Π΅ΡΡΠΈΡ. ΠΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ Π±Π°Π½ ΠΎΡ Π₯Π°Π±ΡΠ°
ΠΠΎΠ³Π΄Π° Ρ ΠΏΡΠΎΡΠ΅ΡΡΡΠΈΠ» ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ Π½Π° ΡΠ΅ΠΌΡ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΡΡΠΈ Π² python, Π²ΡΠ±ΡΠ°Π» Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΡΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Ρ multiprocessing.dummy, ΡΠΎ Ρ Π·Π°ΠΌΠ΅ΡΠΈΠ», ΡΡΠΎ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΡΡΡΡ ΠΏΠΎΡΠ²ΠΈΠ»ΠΈΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
SQLite3 Π½Π΅ Ρ
ΠΎΡΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ ΠΎΠ΄Π½ΠΈΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ.
Π€ΠΈΠΊΡΠΈΡΡΡ check_same_thread=False
, Π½ΠΎ ΡΡΠ° ΠΎΡΠΈΠ±ΠΊΠ° Π½Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½Π°Ρ, ΠΏΡΠΈ ΠΏΠΎΠΏΡΡΠΊΠ΅ Π²ΡΡΠ°Π²ΠΊΠΈ Π² Π±Π°Π·Ρ ΠΈΠ½ΠΎΠ³Π΄Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Ρ ΡΠ°ΠΊ ΠΈ Π½Π΅ ΡΠΌΠΎΠ³ ΡΠ΅ΡΠΈΡΡ.
ΠΠΎΡΡΠΎΠΌΡ Ρ ΡΠ΅ΡΠ°Ρ ΠΎΡΠΊΠ°Π·Π°ΡΡΡΡ ΠΎΡ ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎΠΉ Π²ΡΡΠ°Π²ΠΊΠΈ ΡΡΠ°ΡΠ΅ΠΉ ΡΡΠ°Π·Ρ Π² Π±Π°Π·Ρ ΠΈ, Π²ΡΠΏΠΎΠΌΠΈΠ½Π°Ρ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ cointegrated, ΡΠ΅ΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΠΉΠ»Ρ, Ρ.ΠΊ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΡΡ Π² ΡΠ°ΠΉΠ» Π½Π΅Ρ.
Π₯Π°Π±Ρ Π½Π°ΡΠΈΠ½Π°Π΅Ρ Π±Π°Π½ΠΈΡΡ Π·Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ ΡΡΠ΅Ρ
ΠΏΠΎΡΠΎΠΊΠΎΠ².
ΠΡΠΎΠ±ΠΎ ΡΡΡΠ½ΡΠ΅ ΠΏΠΎΠΏΡΡΠΊΠΈ Π΄ΠΎΡΡΡΡΠ°ΡΡΡΡ Π΄ΠΎ Π₯Π°Π±ΡΠ° ΠΌΠΎΠ³ΡΡ Π·Π°ΠΊΠΎΠ½ΡΠΈΡΡΡ Π±Π°Π½ΠΎΠΌ ip Π½Π° ΠΏΠ°ΡΡ ΡΠ°ΡΠΎΠ². Π’Π°ΠΊ ΡΡΠΎ ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΠΈΡΡ 3 ΠΏΠΎΡΠΎΠΊΠ°, Π½ΠΎ ΠΈ ΡΡΠΎ ΡΠΆΠ΅ Ρ
ΠΎΡΠΎΡΠΎ, ΡΠ°ΠΊ Π²ΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ΅Π±ΠΎΡΠ° 100 ΡΡΠ°ΡΠ΅ΠΉ ΡΠΌΠ΅Π½ΡΡΠ°Π΅ΡΡΡ Ρ 26 Π΄ΠΎ 12 ΡΠ΅ΠΊΡΠ½Π΄.
Π‘ΡΠΎΠΈΡ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ ΡΡΠ° Π²Π΅ΡΡΠΈΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π½Π΅ΡΡΠ°Π±ΠΈΠ»ΡΠ½Π°, ΠΈ Π½Π° Π±ΠΎΠ»ΡΡΠΎΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π΅ ΡΡΠ°ΡΠ΅ΠΉ ΡΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈ ΠΎΡΠ²Π°Π»ΠΈΠ²Π°Π΅ΡΡΡ.
async_v1.py
from bs4 import BeautifulSoup
import requests
import os, sys
import json
from multiprocessing.dummy import Pool as ThreadPool
from datetime import datetime
import logging
def worker(i):
currentFile = "files\{}.json".format(i)
if os.path.isfile(currentFile):
logging.info("{} - File exists".format(i))
return 1
url = "https://m.habr.com/post/{}".format(i)
try: r = requests.get(url)
except:
with open("req_errors.txt") as file:
file.write(i)
return 2
# ΠΠ°ΠΏΠΈΡΡ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΡΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ΅ΡΠ²Π΅Ρ
if (r.status_code == 503):
with open("Error503.txt", "a") as write_file:
write_file.write(str(i) + "n")
logging.warning('{} / 503 Error'.format(i))
# ΠΡΠ»ΠΈ ΠΏΠΎΡΡΠ° Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΈΠ»ΠΈ ΠΎΠ½ Π±ΡΠ» ΡΠΊΡΡΡ
if (r.status_code != 200):
logging.info("{} / {} Code".format(i, r.status_code))
return r.status_code
html_doc = r.text
soup = BeautifulSoup(html_doc, 'html5lib')
try:
author = soup.find(class_="tm-user-info__username").get_text()
timestamp = soup.find(class_='tm-user-meta__date')
timestamp = timestamp['title']
content = soup.find(id="post-content-body")
content = str(content)
title = soup.find(class_="tm-article-title__text").get_text()
tags = soup.find(class_="tm-article__tags").get_text()
tags = tags[5:]
# ΠΠ΅ΡΠΊΠ°, ΡΡΠΎ ΠΏΠΎΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΎΠΌ ΠΈΠ»ΠΈ ΡΡΡΠΎΡΠΈΠ°Π»ΠΎΠΌ.
tm_tag = soup.find(class_="tm-tags tm-tags_post").get_text()
rating = soup.find(class_="tm-votes-score").get_text()
except:
author = title = tags = timestamp = tm_tag = rating = "Error"
content = "ΠΡΠΈ ΠΏΠ°ΡΡΠΈΠ½Π³Π΅ ΡΡΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ°."
logging.warning("Error parsing - {}".format(i))
with open("Errors.txt", "a") as write_file:
write_file.write(str(i) + "n")
# ΠΠ°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ ΡΡΠ°ΡΡΡ Π² json
try:
article = [i, timestamp, author, title, content, tm_tag, rating, tags]
with open(currentFile, "w") as write_file:
json.dump(article, write_file)
except:
print(i)
raise
if __name__ == '__main__':
if len(sys.argv) < 3:
print("ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ min ΠΈ max. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅: async_v1.py 1 100")
sys.exit(1)
min = int(sys.argv[1])
max = int(sys.argv[2])
# ΠΡΠ»ΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ² >3
# ΡΠΎ Ρ
Π°Π±Ρ Π±Π°Π½ΠΈΡ ipΡΠ½ΠΈΠΊ Π½Π° Π²ΡΠ΅ΠΌΡ
pool = ThreadPool(3)
# ΠΡΡΡΠ΅Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π·Π°ΠΏΡΡΠΊ ΠΏΠΎΡΠΎΠΊΠΎΠ²
start_time = datetime.now()
results = pool.map(worker, range(min, max))
# ΠΠΎΡΠ»Π΅ Π·Π°ΠΊΡΡΡΠΈΡ Π²ΡΠ΅Ρ
ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΏΠ΅ΡΠ°ΡΠ°Π΅ΠΌ Π²ΡΠ΅ΠΌΡ
pool.close()
pool.join()
print(datetime.now() - start_time)
Π’ΡΠ΅ΡΡΡ Π²Π΅ΡΡΠΈΡ. Π€ΠΈΠ½Π°Π»ΡΠ½Π°Ρ
ΠΡΠ»Π°ΠΆΠΈΠ²Π°Ρ Π²ΡΠΎΡΡΡ Π²Π΅ΡΡΠΈΡ, Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ», ΡΡΠΎ Ρ Π₯Π°Π±ΡΠ°, Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎ, Π΅ΡΡΡ API, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΎΠ±ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΌΠΎΠ±ΠΈΠ»ΡΠ½Π°Ρ Π²Π΅ΡΡΠΈΡ ΡΠ°ΠΉΡΠ°. ΠΠ°Π³ΡΡΠΆΠ°Π΅ΡΡΡ ΠΎΠ½ΠΎ Π±ΡΡΡΡΠ΅Π΅, ΡΠ΅ΠΌ ΠΌΠΎΠ±ΠΈΠ»ΡΠ½Π°Ρ Π²Π΅ΡΡΠΈΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ json, ΠΊΠΎΡΠΎΡΡΠΉ Π΄Π°ΠΆΠ΅ ΠΏΠ°ΡΡΠΈΡΡ ΠΎΡΠΎΠ±ΠΎ Π½Π΅ Π½ΡΠΆΠ½ΠΎ. Π ΠΈΡΠΎΠ³Π΅ Ρ ΡΠ΅ΡΠΈΠ» Π·Π°Π½ΠΎΠ²ΠΎ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°ΡΡ ΠΌΠΎΠΉ ΡΠΊΡΠΈΠΏΡ.
ΠΡΠ°ΠΊ, ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ² ΠΏΠΎ
async_v2.py
import requests
import os, sys
import json
from multiprocessing.dummy import Pool as ThreadPool
from datetime import datetime
import logging
def worker(i):
currentFile = "files\{}.json".format(i)
if os.path.isfile(currentFile):
logging.info("{} - File exists".format(i))
return 1
url = "https://m.habr.com/kek/v1/articles/{}/?fl=ru%2Cen&hl=ru".format(i)
try:
r = requests.get(url)
if r.status_code == 503:
logging.critical("503 Error")
return 503
except:
with open("req_errors.txt") as file:
file.write(i)
return 2
data = json.loads(r.text)
if data['success']:
article = data['data']['article']
id = article['id']
is_tutorial = article['is_tutorial']
time_published = article['time_published']
comments_count = article['comments_count']
lang = article['lang']
tags_string = article['tags_string']
title = article['title']
content = article['text_html']
reading_count = article['reading_count']
author = article['author']['login']
score = article['voting']['score']
data = (id, is_tutorial, time_published, title, content, comments_count, lang, tags_string, reading_count, author, score)
with open(currentFile, "w") as write_file:
json.dump(data, write_file)
if __name__ == '__main__':
if len(sys.argv) < 3:
print("ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ min ΠΈ max. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅: asyc.py 1 100")
sys.exit(1)
min = int(sys.argv[1])
max = int(sys.argv[2])
# ΠΡΠ»ΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ² >3
# ΡΠΎ Ρ
Π°Π±Ρ Π±Π°Π½ΠΈΡ ipΡΠ½ΠΈΠΊ Π½Π° Π²ΡΠ΅ΠΌΡ
pool = ThreadPool(3)
# ΠΡΡΡΠ΅Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π·Π°ΠΏΡΡΠΊ ΠΏΠΎΡΠΎΠΊΠΎΠ²
start_time = datetime.now()
results = pool.map(worker, range(min, max))
# ΠΠΎΡΠ»Π΅ Π·Π°ΠΊΡΡΡΠΈΡ Π²ΡΠ΅Ρ
ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΏΠ΅ΡΠ°ΡΠ°Π΅ΠΌ Π²ΡΠ΅ΠΌΡ
pool.close()
pool.join()
print(datetime.now() - start_time)
Π Π½Π΅ΠΌ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΠ΅Ρ ΠΏΠΎΠ»Ρ, ΠΎΡΠ½ΠΎΡΡΡΠΈΠ΅ΡΡ ΠΊΠ°ΠΊ ΠΊ ΡΠ°ΠΌΠΎΠΉ ΡΡΠ°ΡΡΠ΅, ΡΠ°ΠΊ ΠΈ ΠΊ Π°Π²ΡΠΎΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π΅Ρ Π½Π°ΠΏΠΈΡΠ°Π».
API.png
Π― Π½Π΅ ΡΡΠ°Π» Π΄Π°ΠΌΠΏΠΈΡΡ ΠΏΠΎΠ»Π½ΡΠΉ json ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ°ΡΡΠΈ, Π° ΡΠΎΡ ΡΠ°Π½ΡΠ» Π»ΠΈΡΡ Π½ΡΠΆΠ½ΡΠ΅ ΠΌΠ½Π΅ ΠΏΠΎΠ»Ρ:
- id
- is_tutorial
- time_published
- title
- content
- comments_count
- lang β ΡΠ·ΡΠΊ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°ΠΏΠΈΡΠ°Π½Π° ΡΡΠ°ΡΡΡ. ΠΠΎΠΊΠ° ΡΡΠΎ Π² Π½Π΅ΠΉ ΡΠΎΠ»ΡΠΊΠΎ en ΠΈ ru.
- tags_string β Π²ΡΠ΅ ΡΠ΅Π³ΠΈ ΠΈΠ· ΠΏΠΎΡΡΠ°
- reading_count
- author
- score β ΡΠ΅ΠΉΡΠΈΠ½Π³ ΡΡΠ°ΡΡΠΈ.
Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ API, Ρ ΡΠΌΠ΅Π½ΡΡΠΈΠ» Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠΊΡΠΈΠΏΡΠ° Π΄ΠΎ 8 ΡΠ΅ΠΊΡΠ½Π΄ Π½Π° 100 url.
ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΌΡ ΡΠΊΠ°ΡΠ°Π»ΠΈ Π½ΡΠΆΠ½ΡΠ΅ Π½Π°ΠΌ Π΄Π°Π½Π½ΡΠ΅, Π½ΡΠΆΠ½ΠΎ ΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΈ Π²Π½Π΅ΡΡΠΈ Π² Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ . Π‘ ΡΡΠΈΠΌ ΡΠΎΠΆΠ΅ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌ:
parser.py
import json
import sqlite3
import logging
from datetime import datetime
def parser(min, max):
conn = sqlite3.connect('habr.db')
c = conn.cursor()
c.execute('PRAGMA encoding = "UTF-8"')
c.execute('PRAGMA synchronous = 0') # ΠΡΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ Π·Π°ΠΏΠΈΡΠΈ, ΡΠ°ΠΊ ΡΠΊΠΎΡΠΎΡΡΡ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ Π² ΡΠ°Π·Ρ.
c.execute("CREATE TABLE IF NOT EXISTS articles(id INTEGER, time_published TEXT, author TEXT, title TEXT, content TEXT,
lang TEXT, comments_count INTEGER, reading_count INTEGER, score INTEGER, is_tutorial INTEGER, tags_string TEXT)")
try:
for i in range(min, max):
try:
filename = "files\{}.json".format(i)
f = open(filename)
data = json.load(f)
(id, is_tutorial, time_published, title, content, comments_count, lang,
tags_string, reading_count, author, score) = data
# Π Π°Π΄ΠΈ Π»ΡΡΡΠ΅ΠΉ ΡΠΈΡΠ°Π΅ΠΌΠΎΡΡΠΈ Π±Π°Π·Ρ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠ΅Π½Π΅Π±ΡΠ΅ΡΡ ΡΠΈΡΠ°Π΅ΠΌΠΎΡΡΡΡ ΠΊΠΎΠ΄Π°. ΠΠ»ΠΈ Π½Π΅Ρ?
# ΠΡΠ»ΠΈ Π²Π°ΠΌ ΡΠ°ΠΊ ΠΊΠ°ΠΆΠ΅ΡΡΡ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΊΠΎΡΡΠ΅ΠΆ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ data. Π Π΅ΡΠ°ΡΡ Π²Π°ΠΌ.
c.execute('INSERT INTO articles VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (id, time_published, author,
title, content, lang,
comments_count, reading_count,
score, is_tutorial,
tags_string))
f.close()
except IOError:
logging.info('FileNotExists')
continue
finally:
conn.commit()
start_time = datetime.now()
parser(490000, 490918)
print(datetime.now() - start_time)
Π‘ΡΠ°ΡΠΈΡΡΠΈΠΊΠ°
ΠΡ ΠΈ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎ, Π½Π°ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·Π²Π»Π΅ΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠΈ ΠΈΠ· Π΄Π°Π½Π½ΡΡ :
- ΠΠ· ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡΡ 490 406 Π±ΡΠ»ΠΎ ΡΠΊΠ°ΡΠ°Π½ΠΎ Π»ΠΈΡΡ 228 512 ΡΡΠ°ΡΠ΅ΠΉ. ΠΠΎΠ»ΡΡΠ°Π΅ΡΡΡ, ΡΡΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ(261894) ΡΡΠ°ΡΠ΅ΠΉ Π½Π° Ρ Π°Π±ΡΠ΅ Π±ΡΠ»ΠΎ ΡΠΊΡΡΡΠΎ ΠΈΠ»ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΎ.
- ΠΡΡ Π±Π°Π·Π°, ΡΠΎΡΡΠΎΡΡΠ°Ρ ΠΈΠ· ΠΏΠΎΡΡΠΈ ΠΏΠΎΠ»ΡΠΌΠΈΠ»Π»ΠΈΠΎΠ½Π° ΡΡΠ°ΡΠ΅ΠΉ, Π²Π΅ΡΠΈΡ 2.95 ΠΠ±. Π ΡΠΆΠ°ΡΠΎΠΌ Π²ΠΈΠ΄Π΅ β 495 ΠΠ±.
- ΠΡΠ΅Π³ΠΎ Π½Π° Π₯Π°Π±ΡΠ΅ Π°Π²ΡΠΎΡΠ°ΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ 37804 ΡΠ΅Π»ΠΎΠ²Π΅ΠΊ. ΠΠ°ΠΏΠΎΠΌΠΈΠ½Π°Ρ, ΡΡΠΎ ΡΡΠΎ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠ° ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ· ΠΆΠΈΠ²ΡΡ ΠΏΠΎΡΡΠΎΠ².
- Π‘Π°ΠΌΡΠΉ ΠΏΡΠΎΠ΄ΡΠΊΡΠΈΠ²Π½ΡΠΉ Π°Π²ΡΠΎΡ Π½Π° Π₯Π°Π±ΡΠ΅ β
alizar β 8774 ΡΡΠ°ΡΡΠΈ. Π‘ΡΠ°ΡΡΡ Ρ ΡΠ°ΠΌΡΠΌ Π±ΠΎΠ»ΡΡΠΈΠΌ ΡΠ΅ΠΉΡΠΈΠ½Π³ΠΎΠΌ β 1448 ΠΏΠ»ΡΡΠΎΠ²Π‘Π°ΠΌΠ°Ρ ΡΠΈΡΠ°Π΅ΠΌΠ°Ρ ΡΡΠ°ΡΡΡ β 1660841 ΠΏΡΠΎΡΠΌΠΎΡΡΠΎΠ²Π‘Π°ΠΌΠ°Ρ ΠΎΠ±ΡΡΠΆΠ΄Π°Π΅ΠΌΠ°Ρ ΡΡΠ°ΡΡΡ β 2444 ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΡ
ΠΡ ΠΈ Π² Π²ΠΈΠ΄Π΅ ΡΠΎΠΏΠΎΠ²Π’ΠΎΠΏ 15 Π°Π²ΡΠΎΡΠΎΠ²
Π’ΠΎΠΏ 15 ΠΏΠΎ ΡΠ΅ΠΉΡΠΈΠ½Π³Ρ
Π’ΠΎΠΏ 15 ΡΠΈΡΠ°Π΅ΠΌΡΡ
Π’ΠΎΠΏ 15 ΠΎΠ±ΡΡΠΆΠ΄Π°Π΅ΠΌΡΡ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com