获取页面所有链接的方法

package com.shishike.susie.utility;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;

public class JsoupTool {
    ArrayList<String> baseUrl = new ArrayList<>();
    ArrayList<String> addedUrl = new ArrayList<>();

    public ArrayList<String> getAllUrls(String urls) {

        urls="http://jira.shishike.com/secure/Dashboard.jspa?selectPageId=10700";
        ArrayList<String> allUrls = new ArrayList<>();
        ArrayList<String> baseUrls = getBaseUrls(urls);

        for (String baseUrl : baseUrls) {

            allUrls.addAll(getImportsUrl(baseUrl));
            allUrls.addAll(getMediaUrl(baseUrl));
            allUrls.addAll(getLinkUrl(baseUrl));
        }
        return allUrls;
    }

    private ArrayList<String> getBaseUrls(String urls) {

        addedUrl.add(urls);
        ArrayList<String> allUrls = new ArrayList<>();
        ArrayList<String> baseUrl = new ArrayList<>();
        allUrls = getLinkUrl(urls);
        for (String url : allUrls) {
            if (url.contains(".html") || url.endsWith("/"))
                baseUrl.add(url);
        }
        for (int i = 0; i < baseUrl.size() - 1; i++) {
            for (int j = i + 1; j < baseUrl.size() - 1; j++) {
                if (baseUrl.get(j).equals(baseUrl.get(i)))
                    baseUrl.remove(j);
            }
            if (!baseUrl.get(i).contains("xxx.com"))
                baseUrl.remove(i);
        }
        this.baseUrl.addAll(baseUrl);
        for (int i = 0; i < baseUrl.size() - 1; i++) {
            baseUrl.remove(0);
            String url = baseUrl.get(i);
            if (!addedUrl.contains(url) && url.contains("xxx.com")) {
                // System.out.println("begin debug");
                // System.out.println(url);
                // System.out.println("end debug");
                getBaseUrls(url);
                // addedUrl.add(url);
            }
        }
        for (int i = 0; i < this.baseUrl.size() - 1; i++) {
            for (int j = i + 1; j < this.baseUrl.size() - 1; j++) {
                if (this.baseUrl.get(j).equals(this.baseUrl.get(i))) {
                    this.baseUrl.remove(j);
                }
            }
            if (!this.baseUrl.get(i).contains("xxx.com"))
                this.baseUrl.remove(i);
        }
        return this.baseUrl;
    }

    private ArrayList<String> getMediaUrl(String urls) {

        ArrayList<String> allUrls = new ArrayList<>();
        Document doc;
        try {
            doc = Jsoup.connect(urls).get();

            Elements media = doc.select("[src]");

            for (Element src : media) {
                String url = src.attr("abs:src");

                if (!url.isEmpty()) {
                    allUrls.add(url);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return allUrls;
    }

    private ArrayList<String> getImportsUrl(String urls) {

        ArrayList<String> allUrls = new ArrayList<>();
        Document doc;
        try {
            doc = Jsoup.connect(urls).get();

            Elements imports = doc.select("link[href]");

            for (Element src : imports) {
                String url = src.attr("abs:href");

                if (!url.isEmpty()) {
                    allUrls.add(url);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return allUrls;
    }

    private ArrayList<String> getLinkUrl(String urls) {

        ArrayList<String> allUrls = new ArrayList<>();
        Document doc;
        try {

            doc = Jsoup.connect(urls).get();

            Elements links = doc.select("a[href]");

            for (Element src : links) {
                String url = src.attr("abs:href");

                if (!url.isEmpty()) {
                    allUrls.add(url);
                }
            }
            for (int i = 0; i < allUrls.size() - 1; i++) {
                for (int j = i + 1; j < allUrls.size() - 1; j++) {
                    if (allUrls.get(j).equals(allUrls.get(i))) {
                        allUrls.remove(j);
                    }

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return allUrls;
    }

}

 

<think>我们被要求获取浏览器中的所有连接(链接)。根据引用内容,我们有几个可能的方法: 1. 通过读取浏览器的Cookie数据库(引用[1]和引用[3])来获取信息,但这主要是获取Cookie,而不是链接。 2. 通过控制浏览器(引用[2])来获取当前打开的页面元素,从而可能提取链接。 3. 通过直接打开浏览器(引用[4])并导航,但这不是获取已有连接。 用户的需求是“获取浏览器中的所有连接”,这里“连接”可能指的是当前打开的标签页中的链接(URL)或者是浏览器历史记录中的链接?或者是当前页面上的所有超链接? 根据引用[2]的方法,我们可以连接到一个已经打开的浏览器(比如Chrome),然后获取当前页面的所有链接。但是,它只能获取当前页面链接,而不是整个浏览器的所有标签页的链接。 实际上,要获取浏览器中所有打开的标签页的链接,我们可以使用浏览器的调试协议(Chrome DevTools Protocol)。通过Selenium或者直接使用CDP,我们可以获取到所有标签页的URL。 另外,如果用户想要获取的是浏览器历史记录中的链接,那么可能需要读取浏览器的历史记录数据库(同样是一个sqlite数据库)。 由于引用中提到了通过Selenium连接已打开的浏览器,我们可以扩展这个方法,使用Selenium来获取当前激活页面的所有链接(通过查找所有a标签的href属性)。但是,这只能得到当前页面链接,而不是所有标签页。 如何获取所有标签页的链接呢?我们可以使用CDP命令。Selenium 4提供了对Chrome DevTools Protocol (CDP) 的支持,允许我们执行CDP命令。 具体步骤: 1. 首先,确保浏览器以调试模式打开(如引用[2]中,使用`--remote-debugging-port=9222`启动浏览器)。 2. 使用Selenium连接已打开的浏览器。 3. 使用CDP命令获取所有目标(targets),每个标签页就是一个目标。 4. 遍历这些目标,获取每个目标的URL。 但是,注意:CDP命令中,我们可以通过`Target.getTargets`来获取所有的目标(标签页、后台页面等)。然后,我们可以从每个目标中获取URL。 然而,Selenium的CDP支持主要是通过`execute_cdp_cmd`方法。我们可以使用`Target.getTargets`命令。 但是,需要注意的是,Selenium的CDP绑定可能没有直接提供获取所有标签页URL的命令,我们需要调用底层的CDP命令。 参考CDP文档:`Target.getTargets`可以获取所有目标,返回的每个目标对象包含`targetId`和`url`等字段。 因此,我们可以这样做: 步骤: 1. 连接已打开的浏览器(使用Selenium)。 2. 执行CDP命令`Target.getTargets`,获取所有目标。 3. 过滤出类型为`page`的目标(即标签页),并提取URL。 但是,注意:我们连接的是当前会话(即当前标签页),而CDP命令可以获取到所有目标,包括其他标签页。但需要确保我们使用的CDP版本支持。 另外,我们也可以使用`Target.getTargets`命令来获取所有目标,然后直接获取URL。 代码示例: 首先,确保浏览器已经以调试模式启动(端口9222),然后连接: ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=chrome_options) # 使用CDP命令获取所有目标 targets = driver.execute_cdp_cmd("Target.getTargets", {}) # 注意:返回的targets中有一个'targetInfos'列表 for target in targets['targetInfos']: if target['type'] == 'page': # 只关注页面类型 print(target['url']) ``` 但是,需要注意的是,通过CDP获取的目标列表包括浏览器的所有目标,可能包括后台的service worker等,我们只关心标签页(即页面类型)。 另外,这种方法获取的是所有标签页的URL,而不是当前页面内的所有链接(即a标签的href)。如果用户需要的是当前页面内的所有链接,那么我们应该使用: ```python # 获取当前页面的所有链接(a标签的href属性) links = driver.find_elements_by_tag_name('a') for link in links: print(link.get_attribute('href')) ``` 因此,我们需要明确用户的需求: 1. 获取浏览器中所有打开的标签页的URL? 2. 还是获取当前页面中的所有链接(即超链接)? 根据问题“获取浏览器中的所有连接”,可能指的是所有打开的标签页的URL,因为“连接”可能被理解为已经打开的页面(即每个标签页是一个连接)。 但是,也有可能指的是当前页面中的所有超链接(即链接到其他页面链接)。由于问题描述不够清晰,我们可以提供两种方案。 不过,问题中引用的内容主要涉及Cookie和单个页面的控制,并没有直接提到获取所有标签页。但是引用[2]中连接了浏览器,我们可以通过CDP扩展。 因此,我将提供两种方法方法一:获取所有打开的标签页的URL(通过CDP) 方法二:获取当前页面中的所有超链接(通过Selenium查找元素) 由于引用[4]中提到了打开多个标签页,但并没有提到获取所有标签页的URL,所以方法一需要依赖CDP。 另外,注意:CDP命令需要Selenium 4及以上版本。如果使用Selenium 3,可能需要使用其他方式,比如通过浏览器扩展。 所以,我们首先确认用户的需求,或者提供两种可能。 但是,问题只要求“获取浏览器中的所有连接”,没有明确。因此,我们可以先实现获取所有打开的标签页的URL,因为这是浏览器级别的“所有连接”。同时,也可以提供获取当前页面所有超链接方法。 步骤总结: 方法一:获取所有标签页的URL 1. 确保Chrome以调试模式启动(端口9222) 2. 使用Selenium连接 3. 执行CDP命令`Target.getTargets`,获取所有页面目标(type为'page')的URL 方法二:获取当前页面所有超链接 1. 连接浏览器(同上) 2. 使用`driver.find_elements_by_tag_name('a')`获取所有a标签,然后提取href属性 另外,如果用户需要获取历史记录,那又是另一种方法(读取历史记录数据库)。 由于引用中提到了Cookie数据库的位置,历史记录数据库的位置类似,在`User Data\Default\History`(也是sqlite数据库),其中`urls`表存储了历史记录。但这不是本次问题要求的。 因此,我们主要针对方法一(所有标签页)和方法二(当前页面的超链接)进行说明。 代码实现: 方法一(获取所有标签页URL): 注意:需要安装最新版本的Selenium(4.x)和ChromeDriver。 方法二(获取当前页面链接): 这是Selenium的常规操作。 但是,注意:当前页面可能包含多个frame,需要遍历所有frame。或者简单处理,只处理主文档。 为了全面,我们可以考虑处理所有frame中的链接。 下面我们分别给出代码示例: 方法一:获取所有标签页的URL ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options # 配置浏览器调试地址 chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 指定chromedriver路径,或者确保它在环境变量中 driver = webdriver.Chrome(options=chrome_options) # 执行CDP命令获取所有目标 result = driver.execute_cdp_cmd("Target.getTargets", {}) targets = result.get('targetInfos', []) all_urls = [] for target in targets: if target['type'] == 'page': all_urls.append(target['url']) # 也可以获取targetId等其他信息 print("所有标签页的URL:") for url in all_urls: print(url) # 关闭driver(注意:关闭driver不会关闭浏览器) driver.quit() ``` 方法二:获取当前页面所有超链接(包括frame中的) ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=chrome_options) # 切换到主文档 driver.switch_to.default_content() # 定义一个函数,用于递归获取所有frame中的链接 def get_links_in_frames(driver): links = [] # 首先获取当前frame中的所有a标签 elements = driver.find_elements(By.TAG_NAME, 'a') for elem in elements: href = elem.get_attribute('href') if href: links.append(href) # 获取当前文档中的所有frame frames = driver.find_elements(By.TAG_NAME, 'iframe') for frame in frames: # 切换到frame driver.switch_to.frame(frame) links.extend(get_links_in_frames(driver)) # 切换回父frame driver.switch_to.parent_frame() return links all_links = get_links_in_frames(driver) print("当前页面所有链接:") for link in all_links: print(link) driver.quit() ``` 注意:递归获取frame中的链接可能会遇到跨域iframe无法访问的问题(同源策略),但如果是同源则可以访问。 但是,如果用户的需求是获取所有标签页的URL,那么方法一更直接。 因此,我们根据问题描述,提供方法一作为主要方案,同时提供方法二作为补充(如果用户需要的是页面内的链接)。 由于问题没有明确,我们可以先按照方法一(获取所有标签页URL)来回答,因为问题说“浏览器中的所有连接”,这更可能是指所有打开的标签页。 最后,注意:启动浏览器时需要开启调试模式,如: ```bash start chrome.exe --remote-debugging-port=9222 ``` 或者通过Python启动(如引用[2]和[4])。 因此,完整步骤: 1. 启动Chrome浏览器(带调试端口) 2. 运行上述方法一的代码 如果用户没有以调试模式启动浏览器,那么连接会失败。因此,我们需要确保浏览器已经以调试模式启动。 另外,如果用户需要的是其他浏览器(如Firefox),则需要不同的方法。但问题中引用都是Chrome,所以这里只考虑Chrome。 所以,我们回答如下:</think>要使用Python获取浏览器中的所有连接(URL),可以通过以下两种主要方法实现,具体取决于需求是获取当前标签页内的所有链接还是所有已打开标签页的URL: --- ### 方法1:获取当前标签页的所有链接页面元素级) 通过Selenium控制浏览器,提取当前页面中的所有超链接: ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options # 连接已打开的Chrome浏览器(需提前以调试模式启动) chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=chrome_options) # 获取当前页面所有<a>标签的href属性(即链接) all_links = [link.get_attribute("href") for link in driver.find_elements("tag name", "a")] # 过滤无效链接并打印 valid_links = [url for url in all_links if url and url.startswith(("http", "https"))] print("当前页面链接列表:") for link in valid_links: print(link) driver.quit() # 关闭驱动 ``` #### 关键步骤: 1. 启动浏览器时需添加调试参数: ```bash chrome.exe --remote-debugging-port=9222 ``` 2. `find_elements("tag name", "a")` 获取所有`<a>`标签 3. 通过`get_attribute("href")`提取实际URL --- ### 方法2:获取所有已打开标签页的URL(浏览器级) 通过浏览器调试协议(CDP)获取所有标签页的URL: ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=chrome_options) # 使用CDP命令获取所有标签页信息 targets = driver.execute_cdp_cmd("Target.getTargets", {}) all_tabs = [t for t in targets["targetInfos"] if t["type"] == "page"] print("所有标签页URL:") for tab in all_tabs: print(tab["url"]) driver.quit() ``` #### 说明: - `execute_cdp_cmd("Target.getTargets", {})` 调用Chrome DevTools Protocol获取所有目标 - 过滤`type="page"`的项得到标签页 - 直接输出每个标签页的URL(无需加载页面内容) --- ### 注意事项 1. **浏览器调试模式** 必须启动浏览器时添加参数`--remote-debugging-port=9222` 2. **驱动匹配** 需安装与浏览器版本匹配的[ChromeDriver](https://chromedriver.chromium.org/) 3. **隐私限制** 部分链接可能因CORS策略或JavaScript动态生成无法直接获取 4. **历史记录获取**(高级需求) 若需浏览器历史记录,需直接读取SQLite数据库: ```python import sqlite3 history_db = "C:\\Users\\[用户名]\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History" conn = sqlite3.connect(history_db) cursor = conn.execute("SELECT url FROM urls") for row in cursor: print(row[0]) ``` > 提示:方法1获取当前页面链接方法2获取所有标签页URL。根据需求选择方案,动态页面建议结合Selenium等待机制(如`WebDriverWait`)确保内容加载完成[^2][^3]。 --- ### 相关问题 1. 如何通过Python监控浏览器新打开的标签页? 2. Selenium如何正确处理JavaScript动态生成的链接? 3. 除了Chrome,Python如何获取Firefox浏览器的标签页信息? [^1]: 引用自Python操作浏览器Cookie的SQLite数据库方法 [^2]: 引用自Selenium连接已打开浏览器的调试技巧 [^3]: 引用自Chrome浏览器本地数据存储机制说明
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值