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