(原创)使用Python递归获取网页内的所有URL,并进行清洗
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