当前位置:首页 > Software > Python > 正文内容

(原创)使用Python递归获取网页内的所有URL,并进行清洗

chanra1n2年前 (2023-05-14)Python3258
import argparse
import time
from urllib.parse import urljoin, urlparse
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup

def get_links(url, max_depth, current_depth=0, visited=None, urls=None):
    # 如果当前深度等于最大深度,直接返回
    if current_depth == max_depth:
        return

    # 如果visited和urls为空,创建空集合
    if visited is None:
        visited = set()
    if urls is None:
        urls = set()

    # 对URL进行归一化处理
    url = urljoin(url, urlparse(url)._replace(query="").geturl())

    # 如果该URL已经被访问过,直接返回
    if url in visited:
        return
    visited.add(url)

    # 使用Selenium模拟用户在浏览器中访问URL,并获取响应的HTML内容
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    driver = webdriver.Chrome(options=options)
    driver.get(url)
    # 等待页面加载完成
    time.sleep(2)
    html = driver.page_source
    driver.quit()

    # 使用BeautifulSoup库来解析HTML内容,并查找其中的所有链接
    soup = BeautifulSoup(html, 'html.parser')
    links = set()
    for link in soup.find_all('a'):
        href = link.get('href')
        # 对链接进行过滤处理
        if href and re.match(r'^https?://', href):
            # 对URL进行归一化处理
            href = urljoin(href, urlparse(href)._replace(query="").geturl())
            links.add(href)
            # 显示获取到的URL链接
            print(href)

    # 将获取到的链接保存到urls集合中
    urls.update(links)

    # 显示当前已经获取的URL链接数量
    print(f"Current depth: {current_depth}, URLs: {len(urls)}")

    # 递归地访问这些链接,直到达到最大深度为止
    for link in links:
        get_links(link, max_depth, current_depth + 1, visited, urls)

    # 将urls集合中的链接保存到txt文件中
    with open("urls.txt", "a") as f:
        for link in urls:
            f.write(link + "\n")

if __name__ == "__main__":
    # 使用argparse库解析命令行参数
    parser = argparse.ArgumentParser(description='Get all links from a URL')
    parser.add_argument('--url', type=str, help='The URL to get links from')
    parser.add_argument('--depth', type=int, default=2, help='The maximum depth to crawl')
    args = parser.parse_args()

    # 获取命令行参数并运行程序
    if args.url:
        get_links(args.url, args.depth)
    else:
        print("Please specify a URL using the --url option")

上面的代码实现了一个从一个URL中获取所有链接的程序。其基本功能可以总结为以下几点:

通过命令行参数指定要获取链接的URL和最大深度。

对URL进行归一化处理,避免获取到重复的链接。

使用Selenium模拟用户在浏览器中访问URL,并获取响应的HTML内容。

使用BeautifulSoup库来解析HTML内容,并查找其中的所有链接。

递归地访问这些链接,直到达到最大深度为止。

显示当前已经获取的URL链接数量。

将获取到的链接保存到txt文件中。

然而,这个程序也存在一些问题和限制:

程序的执行效率可能较低,因为它需要使用Selenium模拟用户在浏览器中访问URL,并等待页面加载完成,这可能会花费一定的时间。

程序只能获取静态HTML页面中的链接,对于动态页面、JavaScript生成的链接或者需要用户登录才能访问的链接,它可能无法获取到。

程序可能会获取到重复的链接,因为它没有对获取到的链接进行去重处理。

程序可能会因为某些链接无法访问或者访问过程中出现异常而停止执行,因此可能需要添加一些异常处理的代码来保证程序的稳定性。

程序没有对链接进行过滤处理,可能会获取到一些无效的链接或者不符合要求的链接。

为了解决这些问题,可能需要对程序进行一些改进和优化。例如,可以使用多线程或异步IO等技术来提高程序的执行效率;可以使用Selenium的WebDriverWait等工具来等待页面加载完成并处理页面动态内容;可以对获取到的链接进行去重处理,或者使用集合等数据结构来避免获取到重复的链接;可以添加异常处理代码来保证程序的稳定性;可以使用正则表达式或其他方法对链接进行过滤处理,避免获取到无效的链接或者不符合要求的链接。


用法

python get_links.py --url http://test.test


扫描二维码推送至手机访问。

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:https://myfpga.cn/index.php/post/305.html

分享给朋友:

“(原创)使用Python递归获取网页内的所有URL,并进行清洗” 的相关文章

0.Python环境的搭建

0.Python环境的搭建

   请打开网页  https://www.python.org/downloads/windows/    Windows环境下的Python        这里我选择...

1.Python基本的使用

1.Python基本的使用

我们打开python或者通过运行python也可以,请复制如下代码,然后按下Enter键,看看会发生什么?print('\n'.join([''.join([('MyFpga'[(x-y) % len('MyFpga'...

math库的使用

math库的使用

math库包括4个数学常数math.pi      圆周率math.e       自然对数math.inf     正无穷大,负无穷大为-math.infmath.nan     非浮点数标记math库常用函数math.cell(x)      向上取整,返回不小于x的最小整数math.facto...

  索引运算符【】

索引运算符【】

选择字符串的子序列语法【start:finish】        start:子序列开始位置的索引值        finish:子序列结束位置的下一个字符的索引值如果不提供start或者finish,默认start为第一个字符,finish为最后一个字符。例如>>>my_str=...

搜索字符串

搜索字符串

常用搜索字符串中子串的方法str.count(substring)      返回str中substring子串出现的无覆盖的次数str.find(s1)                    返回s1在这个字符串的最低下标,如果字符串中不存在s1,则返回-1str.rfind(s1)       ...