เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr

เจจเจฎเจธเจ•เจพเจฐ. เจ‡เจธ เจจเฉ‚เฉฐ เจฒเจฟเจ–เฉ‡ เจนเฉ‹เจ 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)

เจนเจฐ เจšเฉ€เจœเจผ เจ•เจฒเจพเจธเจฟเจ• เจนเฉˆ - เจ…เจธเฉ€เจ‚ เจธเฉเฉฐเจฆเจฐ เจธเฉ‚เจช เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจฌเฉ‡เจจเจคเฉ€เจ†เจ‚ เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจคเฉ‡เจœเจผ เจชเฉเจฐเฉ‹เจŸเฉ‹เจŸเจพเจˆเจช เจคเจฟเจ†เจฐ เจนเฉˆ. เจ‡เจน เจธเจฟเจฐเจซโ€ฆ

  • เจชเฉฐเจจเจพ เจกเจพเจŠเจจเจฒเฉ‹เจก เจ‡เฉฑเจ• เจฅเฉเจฐเฉˆเจก เจตเจฟเฉฑเจš เจนเฉˆ

  • เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฆเฉ‡ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจตเจฟเฉฑเจš เจฐเฉเจ•เจพเจตเจŸ เจชเจพเจ‰เจ‚เจฆเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจธเจพเจฐเจพ เจกเจพเจŸเจพเจฌเฉ‡เจธ เจ•เจฟเจคเฉ‡ เจจเจนเฉ€เจ‚ เจœเจพเจตเฉ‡เจ—เจพเฅค เจ†เจ–เจผเจฐเจ•เจพเจฐ, เจตเจšเจจเจฌเฉฑเจงเจคเจพ เจธเจพเจฐเฉ‡ เจชเจพเจฐเจธเจฟเฉฐเจ— เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจนเฉ€ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ.
    เจฌเฉ‡เจธเจผเฉฑเจ•, เจคเฉเจธเฉ€เจ‚ เจนเจฐเฉ‡เจ• เจธเฉฐเจฎเจฟเจฒเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจคเจฌเจฆเฉ€เจฒเฉ€เจ†เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจชเจฐ เจซเจฟเจฐ เจธเจ•เฉเจฐเจฟเจชเจŸ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจธเจฎเจพเจ‚ เจฌเจนเฉเจค เจตเจง เจœเจพเจตเฉ‡เจ—เจพเฅค

  • เจชเจนเจฟเจฒเฉ‡ 100 เจฒเฉ‡เจ–เจพเจ‚ เจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจ เจตเจฟเฉฑเจš เจฎเฉˆเจจเฉ‚เฉฐ 000 เจ˜เฉฐเจŸเฉ‡ เจฒเฉฑเจ—เฉ‡เฅค

เจ…เฉฑเจ—เฉ‡ เจฎเฉˆเจ‚ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจฆเจพ เจฒเฉ‡เจ– เจฒเฉฑเจญเจฆเจพ เจนเจพเจ‚ เจธเฉฐเจ—เจ เจฟเจค, เจœเจฟเจธเจจเฉ‚เฉฐ เจฎเฉˆเจ‚ เจชเฉœเฉเจนเจฟเจ† เจ…เจคเฉ‡ เจ‡เจธ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจจเฉ‚เฉฐ เจคเฉ‡เจœเจผ เจ•เจฐเจจ เจฒเจˆ เจ•เฉเจ เจฒเจพเจˆเจซ เจนเฉˆเจ• เจฒเฉฑเจญเฉ‡:

  • เจฎเจฒเจŸเฉ€เจฅเฉเจฐเฉˆเจกเจฟเฉฐเจ— เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจจเจพเจฒ เจ•เจˆ เจตเจพเจฐ เจกเจพเจŠเจจเจฒเฉ‹เจกเจฟเฉฐเจ— เจคเฉ‡เจœเจผ เจนเฉ‹ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค
  • เจคเฉเจธเฉ€เจ‚ เจนเจพเจฌเจฐ เจฆเจพ เจชเฉ‚เจฐเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจจเจนเฉ€เจ‚, เจชเจฐ เจ‡เจธเจฆเจพ เจฎเฉ‹เจฌเจพเจˆเจฒ เจธเฉฐเจธเจ•เจฐเจฃ เจชเฉเจฐเจพเจชเจค เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค
    เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจœเฉ‡เจ•เจฐ เจกเฉˆเจธเจ•เจŸเฉŒเจช เจธเฉฐเจธเจ•เจฐเจฃ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจธเฉฐเจฏเฉเจ•เจค เจฒเฉ‡เจ– เจฆเจพ เจญเจพเจฐ 378 KB เจนเฉˆ, เจคเจพเจ‚ เจฎเฉ‹เจฌเจพเจˆเจฒ เจธเฉฐเจธเจ•เจฐเจฃ เจตเจฟเฉฑเจš เจ‡เจน เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ 126 KB เจนเฉˆเฅค

เจฆเฉ‚เจœเจพ เจธเฉฐเจธเจ•เจฐเจฃ. เจฌเจนเฉเจค เจธเจพเจฐเฉ‡ เจงเจพเจ—เฉ‡, เจนเจฌเจฐ เจคเฉ‹เจ‚ เจ…เจธเจฅเจพเจˆ เจชเจพเจฌเฉฐเจฆเฉ€

เจœเจฆเฉ‹เจ‚ เจฎเฉˆเจ‚ python เจตเจฟเฉฑเจš เจฎเจฒเจŸเฉ€เจฅเฉเจฐเฉˆเจกเจฟเฉฐเจ— เจฆเฉ‡ เจตเจฟเจธเจผเฉ‡ 'เจคเฉ‡ เจ‡เฉฐเจŸเจฐเจจเฉˆเจŸ เจฆเฉ€ เจ–เฉ‹เจœ เจ•เฉ€เจคเฉ€, เจคเจพเจ‚ เจฎเฉˆเจ‚ multiprocessing.dummy เจฆเฉ‡ เจจเจพเจฒ เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจตเจฟเจ•เจฒเจช เจšเฉเจฃเจฟเจ†, เจฎเฉˆเจ‚ เจฆเฉ‡เจ–เจฟเจ† เจ•เจฟ เจฎเจฒเจŸเฉ€เจฅเฉเจฐเฉˆเจกเจฟเฉฐเจ— เจฆเฉ‡ เจจเจพเจฒ-เจจเจพเจฒ เจธเจฎเฉฑเจธเจฟเจ†เจตเจพเจ‚ เจธเจพเจนเจฎเจฃเฉ‡ เจ†เจˆเจ†เจ‚ เจนเจจเฅค

SQLite3 เจ‡เฉฑเจ• เจคเฉ‹เจ‚ เจตเฉฑเจง เจฅเฉเจฐเฉˆเจก เจจเจพเจฒ เจ•เฉฐเจฎ เจจเจนเฉ€เจ‚ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเจพ เจนเฉˆ.
เจธเจฅเจฟเจฐ check_same_thread=False, เจชเจฐ เจ‡เจน เจ—เจฒเจคเฉ€ เจธเจฟเจฐเจซ เจ‡เฉฑเจ• เจจเจนเฉ€เจ‚ เจนเฉˆ, เจœเจฆเฉ‹เจ‚ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเฉฐเจฎเจฟเจฒเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจคเจพเจ‚ เจ•เจˆ เจตเจพเจฐ เจ—เจฒเจคเฉ€เจ†เจ‚ เจนเฉเฉฐเจฆเฉ€เจ†เจ‚ เจนเจจ เจœเฉ‹ เจฎเฉˆเจ‚ เจนเฉฑเจฒ เจจเจนเฉ€เจ‚ เจ•เจฐ เจธเจ•เจฆเจพ เจธเฉ€.

เจ‡เจธ เจฒเจˆ, เจฎเฉˆเจ‚ เจธเจฟเฉฑเจงเฉ‡ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจฒเฉ‡เจ–เจพเจ‚ เจฆเฉ‡ เจคเฉเจฐเฉฐเจค เจธเฉฐเจฎเจฟเจฒเจจ เจจเฉ‚เฉฐ เจ›เฉฑเจกเจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เจฐเจฆเจพ เจนเจพเจ‚ เจ…เจคเฉ‡, เจธเฉฐเจฏเฉเจ•เจค เจนเฉฑเจฒ เจจเฉ‚เฉฐ เจฏเจพเจฆ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ, เจฎเฉˆเจ‚ เจซเจพเจˆเจฒเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เจฐเจฆเจพ เจนเจพเจ‚, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เฉฑเจ• เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจฎเจฒเจŸเฉ€-เจฅเฉเจฐเฉˆเจกเจก เจฒเจฟเจ–เจฃ เจตเจฟเฉฑเจš เจ•เฉ‹เจˆ เจธเจฎเฉฑเจธเจฟเจ† เจจเจนเฉ€เจ‚ เจนเฉˆ.

เจนเฉˆเจฌเจฐ เจคเจฟเฉฐเจจ เจคเฉ‹เจ‚ เจตเฉฑเจง เจฅเจฐเจฟเฉฑเจกเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ 'เจคเฉ‡ เจชเจพเจฌเฉฐเจฆเฉ€ เจฒเจ—เจพเจ‰เจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเจพ เจนเฉˆ.
เจ–เจพเจธ เจคเฉŒเจฐ 'เจคเฉ‡ เจนเฉˆเจฌเจฐ เจคเฉฑเจ• เจœเจพเจฃ เจฆเฉ€เจ†เจ‚ เจœเฉ‹เจธเจผเฉ€เจฒเฉ€เจ†เจ‚ เจ•เฉ‹เจธเจผเจฟเจธเจผเจพเจ‚ เจ•เฉเจ เจ˜เฉฐเจŸเจฟเจ†เจ‚ เจฒเจˆ เจ†เจˆเจชเฉ€ เจชเจพเจฌเฉฐเจฆเฉ€ เจฆเฉ‡ เจจเจพเจฒ เจ–เจคเจฎ เจนเฉ‹ เจธเจ•เจฆเฉ€เจ†เจ‚ เจนเจจ. เจ‡เจธ เจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจฟเจฐเจซ 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 เจนเฉˆ, เจœเจฟเจธ เจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจ เจฆเฉ€ เจตเฉ€ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจ…เฉฐเจค เจตเจฟเฉฑเจš, เจฎเฉˆเจ‚ เจ†เจชเจฃเฉ€ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจฒเจฟเจ–เจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพเฅค

เจ‡เจธ เจฒเจˆ, เจชเจพเจ‡เจ† เจ‡เจน เจฒเจฟเฉฐเจ• API, เจคเฉเจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค

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

เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr

เจฎเฉˆเจ‚ เจนเจฐเฉ‡เจ• เจฒเฉ‡เจ– เจฆเฉ‡ เจชเฉ‚เจฐเฉ‡ เจœเฉ‡เจธเจจ เจจเฉ‚เฉฐ เจกเฉฐเจช เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ, เจชเจฐ เจธเจฟเจฐเจซ เจ‰เจนเจจเจพเจ‚ เจ–เฉ‡เจคเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เฉ€เจคเจพ เจนเฉˆ เจœเจฟเจจเฉเจนเจพเจ‚ เจฆเฉ€ เจฎเฉˆเจจเฉ‚เฉฐ เจฒเฉ‹เฉœ เจนเฉˆ:

  • id
  • is_tutorial
  • เจธเจฎเจพเจ‚_เจชเฉเจฐเจ•เจพเจธเจผเจฟเจค
  • เจฆเจพ เจธเจฟเจฐเจฒเฉ‡เจ–
  • เจธเจฎเฉฑเจ—เจฐเฉ€ เจจเฉ‚เฉฐ
  • เจŸเจฟเฉฑเจชเจฃเฉ€เจ†เจ‚_เจ—เจฟเจฃเจคเฉ€
  • lang เจ‰เจน เจญเจพเจธเจผเจพ เจนเฉˆ เจœเจฟเจธ เจตเจฟเฉฑเจš เจฒเฉ‡เจ– เจฒเจฟเจ–เจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจนเฉเจฃ เจคเฉฑเจ•, เจ‡เจธ เจตเจฟเฉฑเจš เจธเจฟเจฐเจซ en เจ…เจคเฉ‡ ru เจนเฉˆเฅค
  • tags_string - เจชเฉ‹เจธเจŸ เจคเฉ‹เจ‚ เจธเจพเจฐเฉ‡ เจŸเฉˆเจ—
  • เจชเฉœเฉเจนเจจ_เจ—เจฟเจฃเจคเฉ€
  • เจฒเฉ‡เจ–เจ•
  • เจธเจ•เฉ‹เจฐ - เจฒเฉ‡เจ– เจฐเฉ‡เจŸเจฟเฉฐเจ—เฅค

เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚, 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) เจฒเฉ‡เจ– เจฒเฉเจ•เฉ‡ เจœเจพเจ‚ เจฎเจฟเจŸเจพ เจฆเจฟเฉฑเจคเฉ‡ เจ—เจ เจธเจจเฅค
  • เจฒเจ—เจญเจ— เจ…เฉฑเจงเจพ เจฎเจฟเจฒเฉ€เจ…เจจ เจฒเฉ‡เจ–เจพเจ‚ เจตเจพเจฒเฉ‡ เจชเฉ‚เจฐเฉ‡ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจฆเจพ เจญเจพเจฐ 2.95 GB เจนเฉˆเฅค เจธเฉฐเจ•เฉเจšเจฟเจค เจฐเฉ‚เจช เจตเจฟเฉฑเจš - 495 MB.
  • เจ•เฉเฉฑเจฒ เจฎเจฟเจฒเจพ เจ•เฉ‡, 37804 เจฒเฉ‹เจ• เจนเจพเจฌเจฐเฉ‡ เจฆเฉ‡ เจฒเฉ‡เจ–เจ• เจนเจจเฅค เจฎเฉˆเจ‚ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฏเจพเจฆ เจฆเจฟเจตเจพเจ‰เจ‚เจฆเจพ เจนเจพเจ‚ เจ•เจฟ เจ‡เจน เจ…เฉฐเจ•เฉœเฉ‡ เจธเจฟเจฐเจซ เจฒเจพเจˆเจต เจชเฉ‹เจธเจŸเจพเจ‚ เจคเฉ‹เจ‚ เจนเจจเฅค
  • เจนเจพเจฌเจฐเฉ‡ 'เจคเฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจตเฉฑเจง เจฒเจพเจญเจ•เจพเจฐเฉ€ เจฒเฉ‡เจ–เจ• - เจ…เจฒเฉ€เจœเจผเจฐ - 8774 เจฒเฉ‡เจ–เฅค
  • เจšเฉ‹เจŸเฉ€ เจฆเจพ เจฆเจฐเจœเจพ เจฆเจฟเฉฑเจคเจพ เจฒเฉ‡เจ– - 1448 เจชเจฒเฉฑเจธ
  • เจธเจญ เจคเฉ‹เจ‚ เจตเฉฑเจง เจชเฉœเฉเจนเจฟเจ† เจฒเฉ‡เจ– - 1660841 เจตเจพเจฐ เจฆเฉ‡เจ–เจฟเจ† เจ—เจฟเจ†
  • เจธเจญ เจคเฉ‹เจ‚ เจตเฉฑเจง เจšเจฐเจšเจพ เจตเจพเจฒเจพ เจฒเฉ‡เจ– - 2444 เจŸเจฟเฉฑเจชเจฃเฉ€เจ†เจ‚

เจจเจพเจฒ เจจเจพเจฒ, เจธเจฟเจ–เจฐ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจšเจšเฉ‹เจŸเฉ€ เจฆเฉ‡ 15 เจฒเฉ‡เจ–เจ•เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr
เจฐเฉ‡เจŸเจฟเฉฐเจ— เจฆเฉเจ†เจฐเจพ เจธเจฟเจ–เจฐ 15เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr
เจธเจฟเจ–เจฐ เจฆเฉ‡ 15 เจชเฉœเฉเจนเฉ‡เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr
เจธเจฟเจ–เจฐ 15 เจšเจฐเจšเจพ เจ•เฉ€เจคเฉ€เจ‡เฉฑเจ• เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ Habr

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹