Рубрики
Без рубрики

Добраться до философии с Python

Есть известные явления Википедии, которые, нажав на первую ссылку в основном тексте статьи … Теги с Python.

Есть известные явления Википедии, которые, нажав на первую ссылку в основном тексте статьи на английской Википедии, вы в конечном итоге окажусь от Философия страница. Пояснение можно найти здесь Отказ Вкратце, это из-за Википедии Руководство по стилю Руководства Это рекомендую, чтобы статьи начнутся с того, что рассказывает «что или тот предмет, и часто, когда и где».

Это было верно для примерно 97% статей, поэтому существует большая вероятность того, что, введя страницу «Случайная википедия» и следуя процедуре, которую вы действительно получите философию. Я мог бы проверить это вручную, но это не будет разработчиком, не написав несколько кода. Мы начнем с того, как скачать статьи Wikipedia.

Как получить данные

Это просто – просто запросить содержимое и статью с Urllib3 Отказ Википедия следует удобному шаблону для именования его статей. После обычного en.wikipedia.org/ Есть /Wiki а потом /article_name. (или СМИ! Например, мы будем иметь дело с этим позже) en.wikipedia.org/wiki/data_mining Отказ

Во-первых, я создам бассейн, из которого я сделаю запросы в Википедию.

import urllib3
from bs4 import BeautifulSoup

pool = urllib3.PoolManager() 

Отныне я смогу скачать статьи один за другим. Чтобы автоматизировать процесс ползания через сайт, гусенично будет рекурсивным. Каждая итерация его вернет (teake_url, [сканер для сайта link_on]) Рекурсион остановится, на данной глубине. В конце концов, я в конечном итоге с древесной структурой.

def crawl(
    pool: urllib3.PoolManager,
    url,
    phrase=None,
    deep=1,
    sleep_time=0.5,
    n=5,
    prefix="https://en.wikipedia.org",
    verbose=False,
):
    """
    Crawls given Wikipedia `url` (article) with max depth `deep`. For each page
    extracts `n` urls and  if `phrase` is given check if `phrase` in urls.

    Parameters
    ----------
    pool : urllib3.PoolManager
        Request pool
    phrase : str
        Phrase to search for in urls.
    url : str
        Link to wikipedia article
    deep : int
        Depth of crawl
    sleep_time : float
        Sleep time between requests.
    n : int
        Number of links to return
    prefix : str, default="https://en.wikipedia.org""
        Site prefix

    Returns
    -------
    tuple
        Tuple of url, list
    """
    if verbose:
        site = url.split("/")[-1]
        print(f"{deep} Entering {site}")

    # Sleep to avoid getting banned
    time.sleep(sleep_time)
    site = pool.request("GET", url)
    soup = BeautifulSoup(site.data, parser="lxml")

    # Get links from wiki (I'll show it later)
    links = get_links_from_wiki(soup=soup, n=n, prefix=prefix)

    # If phrase was given check if any of the links have it
    is_phrase_present = any([phrase in link for link in links]) and phrase is not None
    if deep > 0 and not is_phrase_present:
        return (
            url,
            [
                crawl(
                    pool=pool,
                    url=url_,
                    phrase=phrase,
                    deep=deep - 1,
                    sleep_time=sleep_time,
                    n=n,
                    prefix=prefix,
                    verbose=verbose,
                )
                for url_ in links
            ],
        )
    return url, links

Если вы внимательно прочитаете код, вы заметите функцию get_links_from_wiki Отказ get_links_from_wiki Функция анализирует статью. Он работает, нахожу Div, который содержит всю статью, затем итерации через все пункты (или списки) и находит все ссылки, которые соответствует шаблону /wiki/article_name Отказ Поскольку в этом шаблоне нет домена, он добавляется в конце.

def get_links_from_wiki(soup, n=5, prefix="https://en.wikipedia.org"):
    """
    Extracts `n` first links from wikipedia articles and adds `prefix` to
    internal links.

    Parameters
    ----------
    soup : BeautifulSoup
        Wikipedia page
    n : int
        Number of links to return
    prefix : str, default="https://en.wikipedia.org""
        Site prefix
    Returns
    -------
    list
        List of links
    """
    arr = []

    # Get div with article contents
    div = soup.find("div", class_="mw-parser-output")

    for element in div.find_all("p") + div.find_all("ul"):
        # In each paragraph find all  and
        # extract "/wiki/article_name"
        for i, a in enumerate(element.find_all("a", href=True)):
            if len(arr) >= n:
                break
            if (
                a["href"].startswith("/wiki/")
                and len(a["href"].split("/")) == 3
                and ("." not in a["href"] and ("(" not in a["href"]))
            ):
                arr.append(prefix + a["href"])
    return arr

Теперь у нас есть все, чтобы проверить явления. Я установлю максимальную глубину до 50 и установить n = 1 (только расширить первую ссылку в статье).

crawl(pool, "https://en.wikipedia.org/wiki/Doggart", phrase="Philosophy", deep=50, n=1, verbose=True)

Выход:

50 Entering Doggart
49 Entering Caroline_Doggart
48 Entering Utrecht
47 Entering Help:Pronunciation_respelling_key
...
28 Entering Mental_state
27 Entering Mind
26 Entering Thought
25 Entering Ideas

('https://en.wikipedia.org/wiki/Doggart',
 [('https://en.wikipedia.org/wiki/Caroline_Doggart',
   [('https://en.wikipedia.org/wiki/Utrecht',
     [('https://en.wikipedia.org/wiki/Help:Pronunciation_respelling_key',
       [('https://en.wikipedia.org/wiki/Pronunciation_respelling_for_English',

...
                                                 [('https://en.wikipedia.org/wiki/Ideas',
                                                   ['https://en.wikipedia.org/wiki/Philosophy'])])])])])])])])])])])])])])])])])])])])])])])])])])

Как вы можете видеть после 25 итераций действительно, мы нашли Философия страница.

Нашел этот пост интересно? Проверьте мой Github @finloop.

Оригинал: “https://dev.to/finloop/getting-to-philosophy-with-python-4nmc”