Всички Habr Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ

Π”ΠΎΠ±ΡŠΡ€ Π΄Π΅Π½. ΠœΠΈΠ½Π°Ρ…Π° 2 Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΎΡ‚ΠΊΠ°ΠΊΡ‚ΠΎ Π΅ написано. послСдна статия относно Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Habr ΠΈ някои Ρ‚ΠΎΡ‡ΠΊΠΈ са ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½ΠΈ.

ΠšΠΎΠ³Π°Ρ‚ΠΎ исках Π΄Π° ΠΈΠΌΠ°ΠΌ ΠΊΠΎΠΏΠΈΠ΅ Π½Π° 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 статии ΠΌΠΈ ΠΎΡ‚Π½Π΅ 8 часа.

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Π½Π°ΠΌΠΈΡ€Π°ΠΌ статията Π½Π° потрСбитСля ΠΊΠΎΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€Π°Π½, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€ΠΎΡ‡Π΅Ρ‚ΠΎΡ… ΠΈ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ… няколко Π»Π°ΠΉΡ„Ρ…Π°ΠΊΠ° Π·Π° ускоряванС Π½Π° Ρ‚ΠΎΠ·ΠΈ процСс:

  • Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° многопоточност ускорява изтСглянСто Π² ΠΏΡŠΡ‚ΠΈ.
  • ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½Π΅ ΠΏΡŠΠ»Π½Π°Ρ‚Π° вСрсия Π½Π° habr, Π° Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° ΠΌΠΎΠ±ΠΈΠ»Π½Π° вСрсия.
    НапримСр, Π°ΠΊΠΎ ΠΊΠΎΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€Π°Π½Π° статия Π² настолната вСрсия Ρ‚Π΅ΠΆΠΈ 378 KB, Ρ‚ΠΎ Π² ΠΌΠΎΠ±ΠΈΠ»Π½Π°Ρ‚Π° вСрсия тя Π²Π΅Ρ‡Π΅ Π΅ 126 KB.

Π’Ρ‚ΠΎΡ€Π° вСрсия. Много Ρ‚Π΅ΠΌΠΈ, Π²Ρ€Π΅ΠΌΠ΅Π½Π½Π° Π·Π°Π±Ρ€Π°Π½Π° ΠΎΡ‚ Habr

ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€Π΅Ρ‚ΡŠΡ€ΡΠΈΡ… ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ ΠΏΠΎ Ρ‚Π΅ΠΌΠ°Ρ‚Π° Π·Π° ΠΌΠ½ΠΎΠ³ΠΎΠ½ΠΈΡˆΠΊΠΎΠ²ΠΎΡΡ‚Ρ‚Π° Π² python, ΠΈΠ·Π±Ρ€Π°Ρ… Π½Π°ΠΉ-простата опция с multiprocessing.dummy, забСлязах, Ρ‡Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈΡ‚Π΅ сС появяват Π·Π°Π΅Π΄Π½ΠΎ с ΠΌΠ½ΠΎΠ³ΠΎΠ½ΠΈΡˆΠΊΠΎΠ²ΠΎΡΡ‚Ρ‚Π°.

SQLite3 Π½Π΅ иска Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ с ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄Π½Π° нишка.
фиксирани check_same_thread=False, Π½ΠΎ Ρ‚Π°Π·ΠΈ Π³Ρ€Π΅ΡˆΠΊΠ° Π½Π΅ Π΅ СдинствСната, ΠΊΠΎΠ³Π°Ρ‚ΠΎ сС ΠΎΠΏΠΈΡ‚Π²Π°ΠΌ Π΄Π° вмъкна Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, понякога Π²ΡŠΠ·Π½ΠΈΠΊΠ²Π°Ρ‚ Π³Ρ€Π΅ΡˆΠΊΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ ΠΌΠΎΠ³Π° Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠ°.

Π—Π°Ρ‚ΠΎΠ²Π° Ρ€Π΅ΡˆΠ°Π²Π°ΠΌ Π΄Π° сС ΠΎΡ‚ΠΊΠ°ΠΆΠ° ΠΎΡ‚ Π½Π΅Π·Π°Π±Π°Π²Π½ΠΎΡ‚ΠΎ вмъкванС Π½Π° статии Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ ΠΈ, ΠΊΠ°Ρ‚ΠΎ си спомням ΠΊΠΎΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€Π°Π½ΠΎΡ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, Ρ€Π΅ΡˆΠ°Π²Π°ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅, Π·Π°Ρ‰ΠΎΡ‚ΠΎ няма ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡ‚ΠΎ писанС във Ρ„Π°ΠΉΠ».

Habr Π·Π°ΠΏΠΎΡ‡Π²Π° Π·Π°Π±Ρ€Π°Π½Π° Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Ρ‚Ρ€ΠΈ нишки.
ОсобСно рСвностнитС ΠΎΠΏΠΈΡ‚ΠΈ Π·Π° достиганС Π΄ΠΎ Habr ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π·Π°Π²ΡŠΡ€ΡˆΠ°Ρ‚ с 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, ΠΊΠΎΠΉΡ‚ΠΎ Π΄ΠΎΡ€ΠΈ Π½Π΅ трябва Π΄Π° сС Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°. Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΏΡ€Π΅Π½Π°ΠΏΠΈΡˆΠ° ΠΎΡ‚Π½ΠΎΠ²ΠΎ сцСнария си.

И Ρ‚Π°ΠΊΠ°, слСд ΠΊΠ°Ρ‚ΠΎ Π½Π°ΠΌΠ΅Ρ€ΠΈ Ρ‚Π°Π·ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠ° 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 Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ

НС ΠΈΠ·Ρ…Π²ΡŠΡ€Π»ΠΈΡ… пълния json Π½Π° всяка статия, Π½ΠΎ Π·Π°ΠΏΠ°Π·ΠΈΡ… само ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π°, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠΌΠ°Ρ… Π½ΡƒΠΆΠ΄Π°:

  • id
  • is_tutorial
  • time_published
  • Π·Π°Π³Π»Π°Π²ΠΈΠ΅
  • ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅
  • comments_count
  • 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 изтСгляния бяха ΠΈΠ·Ρ‚Π΅Π³Π»Π΅Π½ΠΈ само 228 512 статии. Оказва сС, Ρ‡Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π°Ρ‚Π° (261894) ΠΎΡ‚ статиитС Π½Π° Π₯Π°Π±Ρ€Π΅ са скрити ΠΈΠ»ΠΈ ΠΈΠ·Ρ‚Ρ€ΠΈΡ‚ΠΈ.
  • Цялата Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ, ΡΡŠΡΡ‚ΠΎΡΡ‰Π° сС ΠΎΡ‚ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ ΠΌΠΈΠ»ΠΈΠΎΠ½ статии, Ρ‚Π΅ΠΆΠΈ 2.95 GB. Π’ компрСсиран Π²ΠΈΠ΄ - 495 MB.
  • ΠžΠ±Ρ‰ΠΎ 37804 Π΄ΡƒΡˆΠΈ са Π°Π²Ρ‚ΠΎΡ€ΠΈ Π½Π° Π₯Π°Π±Ρ€Π΅. Напомням Π²ΠΈ, Ρ‡Π΅ Ρ‚Π°Π·ΠΈ статистика Π΅ само ΠΎΡ‚ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π° ΠΆΠΈΠ²ΠΎ.
  • Най-продуктивният Π°Π²Ρ‚ΠΎΡ€ Π½Π° Π₯Π°Π±Ρ€Π΅ - Π°Π»ΠΈΠ·Π°Ρ€ - 8774 статии.
  • Най-високо ΠΎΡ†Π΅Π½Π΅Π½Π° статия β€” 1448 плюса
  • Най-Ρ‡Π΅Ρ‚Π΅Π½Π° статия β€” 1660841 показвания
  • Най-обсъТдана статия β€” 2444 ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€Π°

Π•, ΠΏΠΎΠ΄ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° Π²ΡŠΡ€Ρ…ΠΎΠ²Π΅Π’ΠΎΠΏ 15 авториВсички Habr Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ
Π’ΠΎΠΏ 15 ΠΏΠΎ рСйтингВсички Habr Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ
Π’ΠΎΠΏ 15 прочСтСниВсички Habr Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ
ОбсъТдани Ρ‚ΠΎΠΏ 15Всички Habr Π² Π΅Π΄Π½Π° Π±Π°Π·Π° Π΄Π°Π½Π½ΠΈ

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€