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