如何使用selenium浏览整个网站?
有没有办法用 selenium 来访问一个网址(网站)下的所有链接呢?
我的目标是通过 selenium 启动火狐浏览器,打开我选择的一个网址(我已经知道怎么做了,感谢这个网站),然后让火狐浏览器浏览这个网址下的所有页面。如果有人能给我一些提示或帮助,告诉我怎么用 Python 实现这一点,我会非常感激。
5 个回答
这是可以实现的。我用Java的webdriver和URI做了这个,主要是为了找出坏链接。
你可以用webdriver打开网页,然后用“getElements”这个方法获取标签,保存“href”这个值。
接着,使用Java的URL类检查所有链接的状态,并把它们放进一个栈里。
然后从栈里取出链接,用webdriver去“获取”这个链接。再次从页面中获取所有链接,并去掉那些已经在栈里的重复链接。
这样循环下去,直到栈里没有链接为止。
你可以根据自己的需求来更新这个过程,比如设置遍历的层级,排除那些不属于指定网站域名的链接等等。
如果你在实现过程中遇到困难,请留言评论。
Selenium API 提供了很多功能,让你可以进行各种操作,比如输入文字、点击、访问、导航、在不同的框架之间切换、拖放等等。简单来说,你想做的就是浏览网页,点击链接,并在网站内提供不同的URL。如果我理解得没错的话,是的,你完全可以通过 Selenium Webdriver 来实现这些功能。你还可以创建一个属性文件,这样可以更方便地管理和准备,在里面你可以设置不同的属性,比如URL、基础URI等,然后通过 Selenium Webdriver 在不同的浏览器中进行自动化测试。
我知道你想要一个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)。
正如Khyati提到的,这种做法是可行的,但selenium并不是一个网页爬虫或机器人。你需要清楚你想测试的内容和位置。
如果你真的想这么做,我建议你先打开页面,获取所有的元素,然后循环点击那些与导航功能相关的元素(比如“//a”或者超链接)。
不过,如果你这样做,而页面又打开了另一个页面,并且有返回链接的话,你就需要记录下所有访问过的URL,确保不会重复访问同一个页面。
这样做是可行的,但也需要一些逻辑来实现……如果不小心的话,你可能会陷入无尽的循环中。
你可以在一个类里面使用递归的方法,像下面这个例子一样来实现这个功能。
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();
}
}
希望这对你有帮助。