แฒกแแฆแแแ แแจแแแแแแแกแ. 2 แฌแแแ แแแแแแ แ แแช แแแแฌแแ แ.
แ แแแแกแแช แแแแแแแ แแฅแแแแแ Habr-แแก แแกแแ, แแแแแแฌแงแแแขแ แแแแแฌแแ แ แแแ แกแแ แ, แ แแแแแแช แจแแแแแฎแแแแ แแแขแแ แแแแก แแแแ แจแแแแแ แกแก แแแแแชแแแแ แแแแแจแ. แ แแแแ แแแฎแแ แแ แ แ แจแแชแแแแแแก แจแแแฎแแแ - แจแแแแซแแแแ แฌแแแแแแฎแแ แญแ แแแแก แฅแแแจ.
TLDR-
แแแ แกแแ แแก แแแ แแแแ แแแ แกแแ. แแ แแ แแแแ, แแแแ แ แแ แแแแแแ
แแแกแแฌแงแแกแแกแแแแก, แแ แแแแแแฌแงแแแขแ แจแแแแฅแแแ แกแแ แแแขแแก แแ แแขแแขแแแ, แ แแแแแจแแช แกแขแแขแแ แแแแแฎแแแแแ แแ แฉแแแแขแแแ แแแแกแแแแแแ แแแแแแแกแแแแ แแแแแชแแแแ แแแแแจแ. แแ แฏแแ แแแคแแฅแ แแแแก แแแ แแจแ แแแแแแแงแแแ 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-แก, แแแฎแแแ แแ แกแฌแ แแคแ แแ แแขแแขแแแ แแแแ แแ แแก. แแก แฃแแ แแแแโฆ
-
แแแแ แแแก แฉแแแแขแแแ แแแ แแ แ แแแแแจแแ
-
แแฃ แจแแฌแงแแแขแ แกแแ แแแขแแก แจแแกแ แฃแแแแแก, แแแจแแ แแแแแ แแแแแชแแแแ แแแแ แแ แกแแ แฌแแแ. แงแแแแแแแ แแแแก แจแแแแแ, แฉแแแแแ แฎแแ แชแแแแแแแ แแฎแแแแ แงแแแแ แแแแแแแแแแแแก แจแแแแแ.
แ แ แแฅแแ แฃแแแ, แแฅแแแ แจแแแแซแแแแ แจแแแขแแแแ แชแแแแแแแแแ แแแแแชแแแแ แแแแแจแ แงแแแแแ แฉแแกแแแก แจแแแแแ, แแแแ แแ แจแแแแแ แกแแ แแแขแแก แจแแกแ แฃแแแแแก แแ แ แแแแจแแแแแแแแแ แแแแแ แแแแ. -
แแแ แแแแ 100 แกแขแแขแแแก แแแ แฉแแแ 000 แกแแแแ แแแแญแแ แแ.
แจแแแแแ แแแแฃแแแ แแแแฎแแแ แแแแแก แกแขแแขแแแก
- Multithreading-แแก แแแแแงแแแแแ แแฉแฅแแ แแแก แแแแแแขแแแ แแแแก แแ แแแแแ แ.
- แแฅแแแ แจแแแแซแแแแ แแแแฆแแ แแ แ แฐแแแ แแก แกแ แฃแแ แแแ แกแแ, แแ แแแแ แแแกแ แแแแแแฃแ แ แแแ แกแแ.
แแแแแแแแแ, แแฃ แแแกแแขแแแแก แแแ แกแแแจแ แแแแแขแแแ แแ แแแฃแแ แกแขแแขแแ แแฌแแแแก 378 แแ, แแแจแแ แแแแแแฃแ แ แแแ แกแแแจแ แแก แฃแแแ 126 แแ.
แแแแ แ แแแ แกแแ. แแแแ แ แแแแ, แแ แแแแแแ แแแ แซแแแแ แฐแแแ แแกแแแ
แ แแแแกแแช แแแขแแ แแแขแ แแแแแแแแแแแ แ แแแแแแจแ แแฃแแขแแ แแแแแแแก แแแแแแ, แแแแ แฉแแ แฃแแแ แขแแแแกแ แแแ แแแแขแ multiprocessing.dummy-แแ, แจแแแแแฉแแแ, แ แแ แแ แแแแแแแแแช แแแฉแแแ แแ แแแแแแ แแแแแ แแแแกแแแ แแ แแแ.
SQLite3-แก แแ แกแฃแ แก แแ แแแ แแแข แซแแคแแแ แแฃแจแแแแ.
แแแคแแฅแกแแ แแ check_same_thread=False
, แแแแ แแ แแก แจแแชแแแแ แแ แแ แแก แแ แแแแแ แแ, แแแแแชแแแแ แแแแแจแ แฉแแกแแแก แแชแแแแแแแกแแก แฎแแแแแฎแแ แฉแแแแแ แจแแชแแแแแแ, แ แแแแแแ แแแแแแ แแแแช แแแ แแแแแฎแแ แฎแ.
แแแแขแแ, แแ แแแแแแฌแงแแแขแ แฃแแ แ แแฅแแแก แกแขแแขแแแแแก แแงแแกแแแ แแ แฉแแกแแแแ แแแ แแแแแ แแแแแชแแแแ แแแแแจแ แแ, แแแแแฎแกแแแ แแแแแขแแแ แแ แแแฃแแ แแแแแฌแงแแแขแ, แแแแแแฌแงแแแขแ แแแแแแแงแแแ แคแแแแแแ, แ แแแแแ แคแแแแจแ แแ แแแแแแแแแแแแแ แฉแแฌแแ แแก แแ แแแแแแ แแ แแ แแก.
แฐแแแ แ แแฌแงแแแก แแแ แซแแแแแก แกแแแแ แแแขแ แแแแแก แแแแแงแแแแแแกแแแแก.
แแแแกแแแฃแแ แแแแ แแฃแแแแแแแแ แแชแแแแแแแ แฐแแแ แจแ แแแกแแแ แจแแแซแแแแ แแแกแ แฃแแแแก 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)
แแแกแแแ แแแ แกแแ. แกแแแแแแ
แแแแ แ แแแ แกแแแก แแแแแ แแแแกแแก แแฆแแแแแฉแแแ, แ แแ Habr-แก, แฃแแชแ แแ, แแฅแแก 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
- แแ แแก_แขแฃแขแแ แแแแ
- แแ แ_แแแแแฅแแแงแแแแฃแแ
- แกแแแแฃแ แ
- แจแแแแแ แกแ
- แแแแแแขแแ แแแ_แแแแ
- lang แแ แแก แแแ, แ แแแแแแแช แแฌแแ แแแ แกแขแแขแแ. แฏแแ แฏแแ แแแแ แแแก แแฎแแแแ en แแ ru แแฅแแก.
- tags_string - แงแแแแ แขแแแ แแแกแขแแแแ
- reading_count
- แแแขแแ แ
- แฅแฃแแ โ แกแขแแขแแแก แ แแแขแแแแ.
แแแ แแแแ, 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 แกแขแแขแแ แแงแ แแแแแแฌแแ แแแ. แแแแแแแก, แ แแ Habrรฉ-แแ แกแขแแขแแแแแก แแแฎแแแแ แแ แแแขแ (228) แแแแแแฃแแ แแ แฌแแจแแแแ แแงแ.
- แแแแแ แแแแแชแแแแ แแแแ, แ แแแแแแช แจแแแแแแ แแแแฅแแแก แแแฎแแแแ แ แแแแแแแ แกแขแแขแแแกแแแ, แแฌแแแแก 2.95 แแ. แจแแแฃแแจแฃแแ แคแแ แแแ - 495 แแ.
- แกแแแ แแ แฏแแแจแ, Habrรฉ-แแก แแแขแแ แ 37804 แแแแแแแแแ. แจแแแแฎแกแแแแแ, แ แแ แแก แกแขแแขแแกแขแแแ แแฎแแแแ แแแแ แแแกแขแแแแแแ แแ แแก.
- แงแแแแแแ แแ แแแฃแฅแขแแฃแแ แแแขแแ แ แฐแแแ แแแ -
แแแแแแ แ - 8774 แกแขแแขแแ. แงแแแแแแ แ แแแขแแแแฃแแ แกแขแแขแแ - 1448 แแแฃแกแแงแแแแแแ แฌแแแแแฎแฃแแ แกแขแแขแแ โ 1660841 แแแฎแแแงแแแแแแ แแแแฎแแแฃแแ แกแขแแขแแ โ 2444 แแแแแแขแแ แ
แแกแ, แขแแแแแแก แกแแฎแแแขแแ 15 แแแขแแ แ
แขแแ 15 แ แแแขแแแแแ
แฌแแแแแฎแฃแแ แขแแ 15
แแแแฎแแแฃแแ แขแแ 15
แฌแงแแ แ: www.habr.com