如何使用selenium浏览整个网站?

8 投票
5 回答
7339 浏览
提问于 2025-04-18 10:02

有没有办法用 selenium 来访问一个网址(网站)下的所有链接呢?

我的目标是通过 selenium 启动火狐浏览器,打开我选择的一个网址(我已经知道怎么做了,感谢这个网站),然后让火狐浏览器浏览这个网址下的所有页面。如果有人能给我一些提示或帮助,告诉我怎么用 Python 实现这一点,我会非常感激。

5 个回答

0

这是可以实现的。我用Java的webdriver和URI做了这个,主要是为了找出坏链接。

你可以用webdriver打开网页,然后用“getElements”这个方法获取标签,保存“href”这个值。

接着,使用Java的URL类检查所有链接的状态,并把它们放进一个栈里。

然后从栈里取出链接,用webdriver去“获取”这个链接。再次从页面中获取所有链接,并去掉那些已经在栈里的重复链接。

这样循环下去,直到栈里没有链接为止。

你可以根据自己的需求来更新这个过程,比如设置遍历的层级,排除那些不属于指定网站域名的链接等等。

如果你在实现过程中遇到困难,请留言评论。

0

Selenium API 提供了很多功能,让你可以进行各种操作,比如输入文字、点击、访问、导航、在不同的框架之间切换、拖放等等。简单来说,你想做的就是浏览网页,点击链接,并在网站内提供不同的URL。如果我理解得没错的话,是的,你完全可以通过 Selenium Webdriver 来实现这些功能。你还可以创建一个属性文件,这样可以更方便地管理和准备,在里面你可以设置不同的属性,比如URL、基础URI等,然后通过 Selenium Webdriver 在不同的浏览器中进行自动化测试。

1

我知道你想要一个Python的例子,但我刚好在设置一个简单的仓库来进行Protractor测试,而你想做的事情用Protractor来完成其实非常简单(Protractor只是Webdriver的一个封装)。

这里是用JavaScript写的代码:

describe( 'stackoverflow scrapping', function () {
  var ptor = protractor.getInstance();

  beforeEach(function () {
    browser.ignoreSynchronization = true;
  } );

  afterEach(function () {

  } );

  it( 'should find the number of links in a given url', function () {
    browser.get( 'http://stackoverflow.com/questions/24257802/how-to-browse-a-whole-website-using-selenium' );

    var script = function () {
      var cb = arguments[ 0 ];
      var nodes = document.querySelectorAll( 'a' );
      nodes = [].slice.call( nodes ).map(function ( a ) {
        return a.href;
      } );
      cb( nodes );
    };

    ptor.executeAsyncScript( script ).then(function ( res ) {
      var visit = function ( url ) {
        console.log( 'visiting url', url );
        browser.get( url );
        return ptor.sleep( 1000 );
      };

      var doVisit = function () {
        var url = res.pop();
        if ( url ) {
          visit( url ).then( doVisit );
        } else {
          console.log( 'done visiting pages' );
        }
      };

      doVisit();

    } );
  } );

} );

你可以从这里克隆这个仓库。

注意:我知道Protractor可能不是最好的工具,但用它做这个事情实在是太简单了,所以我就试了一下。

我在Firefox上测试过这个(你可以使用firefox-conf分支,但需要手动启动Webdriver),也在Chrome上测试过。如果你使用的是OSX系统,这应该没有问题(前提是你已经安装了Node.js)。

2

正如Khyati提到的,这种做法是可行的,但selenium并不是一个网页爬虫或机器人。你需要清楚你想测试的内容和位置。

如果你真的想这么做,我建议你先打开页面,获取所有的元素,然后循环点击那些与导航功能相关的元素(比如“//a”或者超链接)。

不过,如果你这样做,而页面又打开了另一个页面,并且有返回链接的话,你就需要记录下所有访问过的URL,确保不会重复访问同一个页面。

这样做是可行的,但也需要一些逻辑来实现……如果不小心的话,你可能会陷入无尽的循环中。

5

你可以在一个类里面使用递归的方法,像下面这个例子一样来实现这个功能。

public class RecursiveLinkTest {
    //list to save visited links
    static List<String> linkAlreadyVisited = new ArrayList<String>();
    WebDriver driver;

    public RecursiveLinkTest(WebDriver driver) {
        this.driver = driver;
    }

    public void linkTest() {
        // loop over all the a elements in the page
        for(WebElement link : driver.findElements(By.tagName("a")) {
            // Check if link is displayed and not previously visited
            if (link.isDisplayed() 
                        && !linkAlreadyVisited.contains(link.getText())) {
                // add link to list of links already visited
                linkAlreadyVisited.add(link.getText());
                System.out.println(link.getText());
                // click on the link. This opens a new page
                link.click();
                // call recursiveLinkTest on the new page
                new RecursiveLinkTest(driver).linkTest();
            }
        }
        driver.navigate().back();
    }

    public static void main(String[] args) throws InterruptedException {
        WebDriver driver = new FirefoxDriver();
        driver.get("http://newtours.demoaut.com/");
        // start recursive linkText
        new RecursiveLinkTest(driver).linkTest();
    }
}

希望这对你有帮助。

撰写回答