如何在Python中提取所有网站链接(代码实现指南)

Python如何提取所有网站链接?本文教你使用Python中的requests、requests_html和beautiful soup构建一个爬虫来提取所有网站内部和外部链接。
提取网页的所有链接是网络爬虫的常见任务,构建高级爬虫来抓取某个网站的每个页面以提取数据很有用,也可用于 SEO 诊断过程甚至信息收集阶段进行渗透测试人员。在本教程中,你将学习如何仅使用Requests  和  BeautifulSoup库从零开始在 Python 中构建链接提取器工具。
如何在Python中提取所有网站链接?让我们安装依赖项:

pip3 install requests bs4 colorama

我们将使用请求作出HTTP请求方便,BeautifulSoup解析HTML和彩色光的改变文字颜色。
Python提取所有网站链接示例代码开始:打开一个新的 Python 文件并继续,让我们导入我们需要的模块:
import requests from urllib.parse import urlparse, urljoin from bs4 import BeautifulSoup import colorama

我们将使用colorama只是为了在打印时使用不同的颜色,以区分内部和外部链接:
# init the colorama module colorama.init() GREEN = colorama.Fore.GREEN GRAY = colorama.Fore.LIGHTBLACK_EX RESET = colorama.Fore.RESET YELLOW = colorama.Fore.YELLOW

我们需要两个全局变量,一个用于网站的所有内部链接,另一个用于所有外部链接:
# initialize the set of links (unique links) internal_urls = set() external_urls = set()

  • 内部链接是链接到同一网站其他页面的 URL。
  • 外部链接是链接到其他网站的 URL。
由于并非所有锚标签(a标签)中的链接  都有效(我已经对此进行了试验),有些是指向网站部分的链接,有些是 javascript,所以让我们编写一个函数来验证 URL:
def is_valid(url): """ Checks whether `url` is a valid URL. """ parsed = urlparse(url) return bool(parsed.netloc) and bool(parsed.scheme)

这将确保URL 中存在正确的方案(协议,例如http或https)和域名。
Python如何提取所有网站链接?现在让我们构建一个函数来返回网页的所有有效 URL:
def get_all_website_links(url): """ Returns all URLs that is found on `url` in which it belongs to the same website """ # all URLs of `url` urls = set() # domain name of the URL without the protocol domain_name = urlparse(url).netloc soup = BeautifulSoup(requests.get(url).content, "html.parser")

首先,我初始化了urls集变量,我在这里使用了 Python 集,因为我们不想要冗余链接。
其次,我已经从 URL 中提取了域名,我们需要它来检查我们抓取的链接是外部链接还是内部链接。
如何在Python中提取所有网站链接?第三,我已经下载了网页的 HTML 内容并用一个soup对象包装它以简化 HTML 解析。
让我们所有的HTML一个标签(锚标签包含网页的所有链接):
for a_tag in soup.findAll("a"): href = https://www.lsbin.com/a_tag.attrs.get("href") if href =https://www.lsbin.com/="" or href is None: # href empty tag continue

复制所以我们得到href属性并检查那里是否有东西。否则,我们就继续下一个链接。
由于并非所有链接都是绝对链接,因此我们需要将相对 URL 与其域名连接起来(例如,当href为"/search"且url为"google.com" 时,结果将为"google.com/search"):
# join the URL if it's relative (not absolute link) href = https://www.lsbin.com/urljoin(url, href)

Python提取所有网站链接示例 - 现在我们需要从 URL 中删除HTTP GET参数,因为这会导致集合中的冗余,下面的代码处理:
parsed_href = https://www.lsbin.com/urlparse(href) # remove URL GET parameters, URL fragments, etc. href = parsed_href.scheme +"://" + parsed_href.netloc + parsed_href.path

让我们完成这个功能:
if not is_valid(href): # not a valid URL continue if href in internal_urls: # already in the set continue if domain_name not in href: # external link if href not in external_urls: print(f"{GRAY}[ !] External link: {href}{RESET}") external_urls.add(href) continue print(f"{GREEN}[ *] Internal link: {href}{RESET}") urls.add(href) internal_urls.add(href) return urls

Python如何提取所有网站链接?我们在这里所做的只是检查:
  • 如果 URL 无效,请继续下一个链接。
  • 如果 URL 已经在internal_urls 中,我们也不需要它。
  • 如果 URL 是外部链接,则将其打印为灰色并将其添加到我们的全局external_urls集中并继续下一个链接。
最后,经过所有检查,该 URL 将是一个内部链接,我们将其打印并添加到我们的urls和internal_urls集合中。
上面的函数只会抓取一个特定页面的链接,如果我们想提取整个网站的所有链接怎么办?我们开工吧:
# number of urls visited so far will be stored here total_urls_visited = 0def crawl(url, max_urls=30): """ Crawls a web page and extracts all links. You'll find all links in `external_urls` and `internal_urls` global set variables. params: max_urls (int): number of max urls to crawl, default is 30. """ global total_urls_visited total_urls_visited += 1 print(f"{YELLOW}[ *] Crawling: {url}{RESET}") links = get_all_website_links(url) for link in links: if total_urls_visited > max_urls: break crawl(link, max_urls=max_urls)

该函数抓取网站,即获取第一页的所有链接,然后递归调用自身以跟踪之前提取的所有链接。但是,这可能会导致一些问题,该程序将卡在大型网站(有很多链接)上,例如google.com,因此,我添加了一个max_urls参数以在我们检查到一定数量的 URL 时退出.
Python提取所有网站链接示例介绍:好的,让我们测试一下,确保你在你有权访问的网站上使用它,否则我对你造成的任何伤害概不负责。
if __name__ == "__main__": crawl("https://www.thepythoncode.com") print("[ +] Total Internal links:", len(internal_urls)) print("[ +] Total External links:", len(external_urls)) print("[ +] Total URLs:", len(external_urls) + len(internal_urls)) print("[ +] Total crawled URLs:", max_urls)

如何在Python中提取所有网站链接?我正在这个网站上测试。但是,我强烈建议你不要这样做,这会导致大量请求并挤满 Web 服务器,并且可能会阻止你的 IP 地址。
这是输出的一部分:
如何在Python中提取所有网站链接(代码实现指南)

文章图片
抓取完成后,它将打印提取和抓取的总链接:
[ +] Total Internal links: 90 [ +] Total External links: 137 [ +] Total URLs: 227 [ +] Total crawled URLs: 30

很棒,对吧?我希望本教程对你有所帮助,以激发你使用 Python 构建此类工具。
Python如何提取所有网站链接?有一些网站使用 JavaScript 加载大部分内容,因此,我们需要使用requests_html库,这使我们能够使用Chromium执行 Javascript ,我已经为此编写了一个脚本,只需添加几行(如requests_html 与requests非常相似),请在此处查看。
短时间内多次请求同一个网站可能会导致该网站屏蔽你的IP地址,在这种情况下,你需要为此使用代理服务器。
如果你对抓取图像感兴趣,请查看本教程:如何使用 Python 从网页下载所有图像,或者如果你想提取 HTML 表格,请查看本教程。
我稍微编辑了代码,因此你将能够将输出 URL 保存在文件中,还可以从命令行参数传递 URL,检查完整代码。
想了解有关网页抓取的更多信息?【如何在Python中提取所有网站链接(代码实现指南)】最后,如果你想更多地使用不同的 Python 库进行网络抓取,而不仅仅是 BeautifulSoup,以下课程肯定对你很有价值:
  • 使用 Scrapy Splash Selenium 使用 Python 进行现代网页抓取。
  • Python 2021 中的 Web 抓取和 API 基础知识。

    推荐阅读