āĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡

āĻļā§āĻ­ āĻ…āĻĒāĻ°āĻžāĻšā§āĻ¨. āĻāĻŸāĻŋ āĻ˛ā§‡āĻ–āĻžāĻ° āĻĒāĻ° 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)

āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ•ā§āĻ˛āĻžāĻ¸āĻŋāĻ• - āĻ†āĻŽāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻŋ āĻ¸ā§āĻ¨ā§āĻĻāĻ° āĻ¸ā§āĻ¯ā§āĻĒ, āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻāĻŦāĻ‚ āĻāĻ•āĻŸāĻŋ āĻĻā§āĻ°ā§āĻ¤ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻŸāĻžāĻ‡āĻĒ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĨ¤ āĻ¯ā§‡ āĻļā§āĻ§ā§â€Ļ

  • āĻĒā§ƒāĻˇā§āĻ āĻž āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄ āĻāĻ• āĻĨā§āĻ°ā§‡āĻĄ

  • āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸā§‡āĻ° āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§‡ āĻŦāĻžāĻ§āĻž āĻĻā§‡āĻ¨, āĻ¤āĻžāĻšāĻ˛ā§‡ āĻĒā§āĻ°ā§‹ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸āĻŸāĻŋ āĻ•ā§‹āĻĨāĻžāĻ“ āĻ¯āĻžāĻŦā§‡ āĻ¨āĻžāĨ¤ āĻ¸āĻŦ āĻĒāĻ°ā§‡, āĻĒā§āĻ°āĻ¤āĻŋāĻļā§āĻ°ā§āĻ¤āĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒāĻžāĻ°ā§āĻ¸āĻŋāĻ‚ āĻĒāĻ°ā§‡ āĻ¸āĻžā§āĻšāĻžāĻ˛āĻŋāĻ¤ āĻšāĻ¯āĻŧ.
    āĻ…āĻŦāĻļā§āĻ¯āĻ‡, āĻ†āĻĒāĻ¨āĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ¸āĻ¨ā§āĻ¨āĻŋāĻŦā§‡āĻļā§‡āĻ° āĻĒāĻ°ā§‡ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ‰āĻ˛ā§āĻ˛ā§‡āĻ–āĻ¯ā§‹āĻ—ā§āĻ¯āĻ­āĻžāĻŦā§‡ āĻŦā§ƒāĻĻā§āĻ§āĻŋ āĻĒāĻžāĻŦā§‡āĨ¤

  • āĻĒā§āĻ°āĻĨāĻŽ 100 āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖ āĻ•āĻ°āĻ¤ā§‡ āĻ†āĻŽāĻžāĻ° 000 āĻ˜āĻ¨ā§āĻŸāĻž āĻ¸āĻŽāĻ¯āĻŧ āĻ˛ā§‡āĻ—ā§‡āĻ›ā§‡āĨ¤

āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻ†āĻŽāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ āĻ–ā§āĻāĻœā§‡ āĻ¸āĻŽāĻ¨ā§āĻŦāĻŋāĻ¤, āĻ¯āĻž āĻ†āĻŽāĻŋ āĻĒāĻĄāĻŧā§‡āĻ›āĻŋ āĻāĻŦāĻ‚ āĻāĻ‡ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻŸāĻŋāĻ•ā§‡ āĻĻā§āĻ°ā§āĻ¤ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ•āĻ¯āĻŧā§‡āĻ•āĻŸāĻŋ āĻ˛āĻžāĻ‡āĻĢ āĻšā§āĻ¯āĻžāĻ• āĻĒā§‡āĻ¯āĻŧā§‡āĻ›āĻŋ:

  • āĻŽāĻžāĻ˛ā§āĻŸāĻŋāĻĨā§āĻ°ā§‡āĻĄāĻŋāĻ‚ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ…āĻ¨ā§‡āĻ• āĻ¸āĻŽāĻ¯āĻŧ āĻĄāĻžāĻ‰āĻ¨āĻ˛ā§‹āĻĄā§‡āĻ° āĻ—āĻ¤āĻŋ āĻŦāĻžāĻĄāĻŧā§‡āĨ¤
  • āĻ†āĻĒāĻ¨āĻŋ āĻšāĻžāĻŦāĻ°ā§‡āĻ° āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻĒā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ āĻ¨āĻž, āĻ¤āĻŦā§‡ āĻāĻ° āĻŽā§‹āĻŦāĻžāĻ‡āĻ˛ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖāĨ¤
    āĻ‰āĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§‚āĻĒ, āĻ¯āĻĻāĻŋ āĻĄā§‡āĻ¸ā§āĻ•āĻŸāĻĒ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸āĻŽāĻ¨ā§āĻŦāĻŋāĻ¤ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡āĻ° āĻ“āĻœāĻ¨ 378 KB āĻšāĻ¯āĻŧ, āĻ¤āĻŦā§‡ āĻŽā§‹āĻŦāĻžāĻ‡āĻ˛ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻāĻŸāĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ 126 KBāĨ¤

āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖāĨ¤ āĻ…āĻ¨ā§‡āĻ• āĻĨā§āĻ°ā§‡āĻĄ, āĻšāĻžāĻŦāĻ° āĻĨā§‡āĻ•ā§‡ āĻ¸āĻžāĻŽāĻ¯āĻŧāĻŋāĻ• āĻ¨āĻŋāĻˇā§‡āĻ§āĻžāĻœā§āĻžāĻž

āĻ¯āĻ–āĻ¨ āĻ†āĻŽāĻŋ āĻĒāĻžāĻ‡āĻĨāĻ¨ā§‡ āĻŽāĻžāĻ˛ā§āĻŸāĻŋāĻĨā§āĻ°ā§‡āĻĄāĻŋāĻ‚āĻ¯āĻŧā§‡āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§‡ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻ¨ā§‡āĻŸ āĻ˜āĻžāĻāĻŸāĻžāĻ˜āĻžāĻāĻŸāĻŋ āĻ•āĻ°āĻŋ, āĻ¤āĻ–āĻ¨ āĻ†āĻŽāĻŋ 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

āĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡

āĻ†āĻŽāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡āĻ° āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ json āĻĄāĻžāĻŽā§āĻĒ āĻ•āĻ°āĻŋāĻ¨āĻŋ, āĻ¤āĻŦā§‡ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ†āĻŽāĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°āĻ—ā§āĻ˛āĻŋ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°ā§‡āĻ›āĻŋ:

  • id
  • is_tutorial
  • āĻ¸āĻŽāĻ¯āĻŧ_āĻĒā§āĻ°āĻ•āĻžāĻļāĻŋāĻ¤
  • āĻ–ā§‡āĻ¤āĻžāĻŦ
  • āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§
  • āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯_āĻ—āĻŖāĻ¨āĻž
  • lang āĻšāĻ˛ āĻ¸ā§‡āĻ‡ āĻ­āĻžāĻˇāĻž āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋ āĻ˛ā§‡āĻ–āĻž āĻšāĻ¯āĻŧāĨ¤ āĻāĻ–āĻ¨ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤, āĻāĻŸāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° en āĻāĻŦāĻ‚ ru āĻ†āĻ›ā§‡āĨ¤
  • tags_string - āĻĒā§‹āĻ¸ā§āĻŸ āĻĨā§‡āĻ•ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŸā§āĻ¯āĻžāĻ—
  • āĻĒāĻĄāĻŧāĻž_āĻ—āĻŖāĻ¨āĻž
  • āĻ˛ā§‡āĻ–āĻ•
  • āĻ¸ā§āĻ•ā§‹āĻ° - āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ āĻ°ā§‡āĻŸāĻŋāĻ‚āĨ¤

āĻāĻ‡āĻ­āĻžāĻŦā§‡, API āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡, āĻ†āĻŽāĻŋ āĻĒā§āĻ°āĻ¤āĻŋ 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 āĻœāĻ¨ HabrÊ āĻāĻ° āĻ˛ā§‡āĻ–āĻ•āĨ¤ āĻ†āĻŽāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŽāĻ¨ā§‡ āĻ•āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĻāĻŋāĻšā§āĻ›āĻŋ āĻ¯ā§‡ āĻāĻ‡ āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨āĻ—ā§āĻ˛āĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ˛āĻžāĻ‡āĻ­ āĻĒā§‹āĻ¸ā§āĻŸ āĻĨā§‡āĻ•ā§‡āĨ¤
  • āĻšāĻžāĻŦā§āĻ°ā§‡-āĻāĻ° āĻ¸āĻŦāĻšā§‡āĻ¯āĻŧā§‡ āĻ‰ā§ŽāĻĒāĻžāĻĻāĻ¨āĻļā§€āĻ˛ āĻ˛ā§‡āĻ–āĻ•- āĻ†āĻ˛āĻŋāĻœāĻžāĻ° - 8774āĻŸāĻŋ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĨ¤
  • āĻļā§€āĻ°ā§āĻˇ āĻ°ā§‡āĻŸ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ — 1448 āĻĒā§āĻ˛āĻžāĻ¸
  • āĻ¸āĻ°ā§āĻŦāĻžāĻ§āĻŋāĻ• āĻĒāĻ āĻŋāĻ¤ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ — 1660841 āĻŦāĻžāĻ° āĻĻā§‡āĻ–āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡
  • āĻ¸āĻ°ā§āĻŦāĻžāĻ§āĻŋāĻ• āĻ†āĻ˛ā§‹āĻšāĻŋāĻ¤ āĻĒā§āĻ°āĻŦāĻ¨ā§āĻ§ — 2444 āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯

āĻ­āĻžāĻ˛, āĻļā§€āĻ°ā§āĻˇ āĻ†āĻ•āĻžāĻ°ā§‡āĻļā§€āĻ°ā§āĻˇ 15 āĻ˛ā§‡āĻ–āĻ•āĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡
āĻ°ā§‡āĻŸāĻŋāĻ‚ āĻĻā§āĻŦāĻžāĻ°āĻž āĻļā§€āĻ°ā§āĻˇ 15āĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡
āĻļā§€āĻ°ā§āĻˇ 15 āĻĒāĻĄāĻŧāĻžāĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡
āĻļā§€āĻ°ā§āĻˇ 15 āĻ†āĻ˛ā§‹āĻšāĻŋāĻ¤āĻ¸āĻŦ āĻšāĻžāĻŦāĻ° āĻāĻ• āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨