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

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

chanra1n1年前 (2023-05-14)Python2737
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,并进行清洗” 的相关文章

math库的使用

math库的使用

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

anaconda打不开的解决方法

anaconda打不开的解决方法

报错内容Navigator Error An unexpected error occurred on Navigator start-up Report Please report this ...

体温打卡python 可通过账户密码获取对应ID号

体温打卡python 可通过账户密码获取对应ID号

仅用于学习和测试,请勿自动填报或者干任何违法的事情import datetime import hashlib import random from urllib.parse import quote import req...

Python自动清理错误图片,深度学习训练数据集准备

Python自动清理错误图片,深度学习训练数据集准备

使用python运行from PIL import Image from pathlib import Path import os   path = r'.'  ...

(原创)使用Python对任意网站图片进行爬取,仅用于学习

(原创)使用Python对任意网站图片进行爬取,仅用于学习

import os import time import argparse import requests import re import io from urllib.parse import ...

(原创)使用Python自动对子文件夹中的图片文件进行重命名

(原创)使用Python自动对子文件夹中的图片文件进行重命名

为了解决Python深度学习的时候,经常遇到的文件名问题import os # 获取指定目录下的所有子文件夹 def get_subfolders(path):     subfolders = []...