рд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ

рдирдорд╕реНрдХрд╛рд░ред рдЗрд╕реЗ рд▓рд┐рдЦреЗ рд╣реБрдП 2 рд╕рд╛рд▓ рд╣реЛ рдЧрдП рд╣реИрдВ. рдЕрдВрддрд┐рдо рд▓реЗрдЦ рд╣реИрдмрд░ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдФрд░ рдХреБрдЫ рдмрд┐рдВрджреБ рдмрджрд▓ рдЧрдП рд╣реИрдВред

рдЬрдм рдореИрдВ рд╣реИрдмрд░ рдХреА рдПрдХ рдкреНрд░рддрд┐ рдЪрд╛рд╣рддрд╛ рдерд╛, рддреЛ рдореИрдВрдиреЗ рдПрдХ рдкрд╛рд░реНрд╕рд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдЬреЛ рд▓реЗрдЦрдХреЛрдВ рдХреА рд╕рднреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рд╣реЗрдЬ рд▓реЗрдЧрд╛ред рдпрд╣ рдХреИрд╕реЗ рд╣реБрдЖ рдФрд░ рдореБрдЭреЗ рдХрд┐рди рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ - рдЖрдк рдХрдЯ рдХреЗ рдиреАрдЪреЗ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЯреАрдПрд▓; рдбреАрдЖрд░ - рдбреЗрдЯрд╛рдмреЗрд╕ рд▓рд┐рдВрдХ

рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг. рдзрд╛рдЧрд╛ рдПрдХ, рд╕рдорд╕реНрдпрд╛рдПрдВ рдЕрдиреЗрдХ

рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЬрд┐рд╕рдореЗрдВ рд▓реЗрдЦ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред рдмрд┐рдирд╛ рджреЛрдмрд╛рд░рд╛ рд╕реЛрдЪреЗ, рдореИрдВрдиреЗ 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 рдШрдВрдЯреЗ рд▓рдЧреЗред

рдЖрдЧреЗ рдореБрдЭреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рд▓реЗрдЦ рдорд┐рд▓рд╛ рд╕рд╣рдПрдХреАрдХреГрдд, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдкрдврд╝рд╛ рдФрд░ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рддреЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд▓рд╛рдЗрдл рд╣реИрдХреНрд╕ рдкрд╛рдП:

  • рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдХрдИ рдмрд╛рд░ рдбрд╛рдЙрдирд▓реЛрдбрд┐рдВрдЧ рдХреА рдЧрддрд┐ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред
  • рдЖрдк habr рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЙрд╕рдХрд╛ рдореЛрдмрд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
    рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдбреЗрд╕реНрдХрдЯреЙрдк рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдПрдХ рд╕рд╣-рдПрдХреАрдХреГрдд рд▓реЗрдЦ рдХрд╛ рд╡рдЬрди 378 KB рд╣реИ, рддреЛ рдореЛрдмрд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 126 KB рд╣реИред

рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг. рдХрдИ рдзрд╛рдЧреЗ, рд╣реИрдмрд░ рд╕реЗ рдЕрд╕реНрдерд╛рдпреА рдкреНрд░рддрд┐рдмрдВрдз

рдЬрдм рдореИрдВрдиреЗ рдкрд╛рдпрдерди рдореЗрдВ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдЗрдВрдЯрд░рдиреЗрдЯ рдЦрдВрдЧрд╛рд▓рд╛, рддреЛ рдореИрдВрдиреЗ рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ.рдбрдореА рдХреЗ рд╕рд╛рде рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛, рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рджрд┐рдЦрд╛рдИ рджреАрдВред

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)

рддреАрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг. рдЕрдВрддрд┐рдо

рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдбреАрдмрдЧ рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ рдЕрдЪрд╛рдирдХ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╣реИрдмрд░ рдХреЗ рдкрд╛рд╕ рдПрдХ рдПрдкреАрдЖрдИ рд╣реИ рдЬрд┐рд╕реЗ рд╕рд╛рдЗрдЯ рдХрд╛ рдореЛрдмрд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдг рдПрдХреНрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдореЛрдмрд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рддреЗрдЬреА рд╕реЗ рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд┐рд░реНрдл 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)

рдЗрд╕рдореЗрдВ рд▓реЗрдЦ рдФрд░ рдЗрд╕реЗ рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЗрдЦрдХ рджреЛрдиреЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдлрд╝реАрд▓реНрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

рдПрдкреАрдЖрдИ.рдкреАрдПрдирдЬреА

рд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ

рдореИрдВрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдЖрд▓реЗрдЦ рдХрд╛ рдкреВрд░рд╛ json рдбрдВрдк рдирд╣реАрдВ рдХрд┐рдпрд╛, рдмрд▓реНрдХрд┐ рдХреЗрд╡рд▓ рд╡реЗ рдлрд╝реАрд▓реНрдб рд╕рд╣реЗрдЬреЗ рдЬрд┐рдирдХреА рдореБрдЭреЗ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА:

  • id
  • is_tutorial
  • рд╕рдордп_рдкреНрд░рдХрд╛рд╢рд┐рдд
  • рд╢реАрд░реНрд╖рдХ
  • рд╕рд╛рдордЧреНрд░реА
  • рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ_рдЧрд┐рдирддреА
  • рд▓реИрдВрдЧ рд╡рд╣ рднрд╛рд╖рд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдм рддрдХ, рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рдПрди рдФрд░ рдЖрд░рдпреВ рд╣реИред
  • tags_string - рдкреЛрд╕реНрдЯ рдХреЗ рд╕рднреА рдЯреИрдЧ
  • рдкрдврд╝рдирд╛_рдЧрд┐рдирддреА
  • рд▓реЗрдЦрдХ
  • рд╕реНрдХреЛрд░ - рд▓реЗрдЦ рд░реЗрдЯрд┐рдВрдЧ.

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдореИрдВрдиреЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдкреНрд░рддрд┐ 8 рдпреВрдЖрд░рдПрд▓ рдкрд░ 100 рд╕реЗрдХрдВрдб рддрдХ рдХрдо рдХрд░ рджрд┐рдпрд╛ред

рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдЗрд╕рд╕реЗ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реБрдИ:

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 рдЬреАрдмреА рд╣реИред рд╕рдВрдкреАрдбрд╝рд┐рдд рд░реВрдк рдореЗрдВ - 495 рдПрдордмреА.
  • рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, 37804 рд▓реЛрдЧ рд╣реЗрдмреЗрд░реЗ рдХреЗ рд▓реЗрдЦрдХ рд╣реИрдВред рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рдпреЗ рдЖрдБрдХрдбрд╝реЗ рдХреЗрд╡рд▓ рд▓рд╛рдЗрд╡ рдкреЛрд╕реНрдЯ рд╕реЗ рд╣реИрдВред
  • рд╣реИрдмреЗ рдкрд░ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рд▓реЗрдЦрдХ - рдЕрд▓реАрдЬрд╝рд╛рд░реЛ - 8774 рд▓реЗрдЦред
  • рдЯреЙрдк рд░реЗрдЯреЗрдб рд▓реЗрдЦ тАФ 1448 рдкреНрд▓рд╕
  • рд╕рд░реНрд╡рд╛рдзрд┐рдХ рдкрдврд╝рд╛ рдЧрдпрд╛ рд▓реЗрдЦ тАУ 1660841 рдмрд╛рд░ рджреЗрдЦрд╛ рдЧрдпрд╛
  • рд╕рд░реНрд╡рд╛рдзрд┐рдХ рдЪрд░реНрдЪрд┐рдд рд▓реЗрдЦ тАФ 2444 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдЦреИрд░, рд╢реАрд░реНрд╖ рдХреЗ рд░реВрдк рдореЗрдВрд╢реАрд░реНрд╖ 15 рд▓реЗрдЦрдХрд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ
рд░реЗрдЯрд┐рдВрдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╢реАрд░реНрд╖ 15рд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ
рд╢реАрд░реНрд╖ 15 рдкрдврд╝реЗрдВрд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ
рд╢реАрд░реНрд╖ 15 рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИрд╕рднреА рд╣рдмрд░ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ