selenium官网是动态网页吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了selenium官网是动态网页吗相关的知识,希望对你有一定的参考价值。

动态网页抓取 (解析真实地址 + selenium)

由于网易云跟帖停止服务,现在已经在此处中更新了新写的第四章。请参照文章:

前面爬取的网页均为静态网页,这样的网页在浏览器中展示的内容都在html源代码中。但是,由于主流网站都使用javascript展现网页内容,和静态网页不同的是,在使用JavaScript时,很多内容并不会出现在HTML源代码中,所以爬取静态网页的技术可能无法正常使用。因此,我们需要用到动态网页抓取的两种技术:通过浏览器审查元素解析真实网页地址和使用selenium模拟浏览器的方法。

本章首先介绍动态网页的实例,让读者了解什么是动态抓取,然后使用上述两种动态网页抓取技术获取动态网页的数据。

4动态抓取的例子

在开始爬取动态网页前,我们还需要了解一种异步更新技术—AJAX(Asynchronous Javascript And XML,异步JavaScript和XML)。它的价值在于通过在后台与服务器进行少量数据交换就可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下对网页的某部分进行更新。一方面减少了网页重复内容的下载,另一方面节省了流量,因此AJAX得到了广泛使用。

相对于使用AJAX网页而言,传统的网页如果需要更新内容,就必须重载整个网页页面。因此,AJAX使得互联网应用程序更小、更快、更友好。但是,AJAX网页的爬虫过程比较麻烦。

首先,让我们来看动态网页的例子。打开笔者博客的Hello World文章,文章地址为:http://www.santostang.com/2018/07/04/hello-world/。网址可能会变更,请进入笔者博客官网找到Hello World文章地址。如图4-1所示,页面下面的评论就是用JavaScript加载的,这些评论数据不会出现在网页源代码中。

为了验证页面下面的评论是用JavaScript加载的,我们可以查看此网页的网页源代码。如图4-2所示,放置该评论的代码里面并没有评论数据,只有一段JavaScript代码,最后呈现出来的数据就是通过JavaScript提取数据加载到源代码进行呈现的。

除了笔者的博客,还可以在天猫电商网站上找到AJAX技术的例子。例如,打开天猫的iPhone XS Max的产品页面,单击“累计评价”,可以发现上面的url地址没有任何改变,没有重新加载整个网页并对网页的评论部分进行更新,如图4-3所示。

如图4-4所示,我们也可以查看此商品网页的源代码,里面并没有用户评论,这一块内容是空白的。

如果使用AJAX加载的动态网页,怎么爬取里面动态加载的内容呢?有两种方法:

(1)通过浏览器审查元素解析地址。

(2)通过Selenium模拟浏览器抓取。

参考技术A

动态网页抓取 (解析真实地址 + selenium)

由于网易云跟帖停止服务,现在已经在此处中更新了新写的第四章。请参照文章:

前面爬取的网页均为静态网页,这样的网页在浏览器中展示的内容都在HTML源代码中。但是,由于主流网站都使用JavaScript展现网页内容,和静态网页不同的是,在使用JavaScript时,很多内容并不会出现在HTML源代码中,所以爬取静态网页的技术可能无法正常使用。因此,我们需要用到动态网页抓取的两种技术:通过浏览器审查元素解析真实网页地址和使用selenium模拟浏览器的方法。

本章首先介绍动态网页的实例,让读者了解什么是动态抓取,然后使用上述两种动态网页抓取技术获取动态网页的数据。

4动态抓取的例子

在开始爬取动态网页前,我们还需要了解一种异步更新技术—AJAX(Asynchronous Javascript And XML,异步JavaScript和XML)。它的价值在于通过在后台与服务器进行少量数据交换就可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下对网页的某部分进行更新。一方面减少了网页重复内容的下载,另一方面节省了流量,因此AJAX得到了广泛使用。

相对于使用AJAX网页而言,传统的网页如果需要更新内容,就必须重载整个网页页面。因此,AJAX使得互联网应用程序更小、更快、更友好。但是,AJAX网页的爬虫过程比较麻烦。

首先,让我们来看动态网页的例子。打开笔者博客的Hello World文章,文章地址为:http://www.santostang.com/2018/07/04/hello-world/。网址可能会变更,请进入笔者博客官网找到Hello World文章地址。如图4-1所示,页面下面的评论就是用JavaScript加载的,这些评论数据不会出现在网页源代码中。

为了验证页面下面的评论是用JavaScript加载的,我们可以查看此网页的网页源代码。如图4-2所示,放置该评论的代码里面并没有评论数据,只有一段JavaScript代码,最后呈现出来的数据就是通过JavaScript提取数据加载到源代码进行呈现的。

除了笔者的博客,还可以在天猫电商网站上找到AJAX技术的例子。例如,打开天猫的iPhone XS Max的产品页面,单击“累计评价”,可以发现上面的url地址没有任何改变,没有重新加载整个网页并对网页的评论部分进行更新,如图4-3所示。

如图4-4所示,我们也可以查看此商品网页的源代码,里面并没有用户评论,这一块内容是空白的。

如果使用AJAX加载的动态网页,怎么爬取里面动态加载的内容呢?有两种方法:

(1)通过浏览器审查元素解析地址。

(2)通过Selenium模拟浏览器抓取。

参考技术B 按F12打开开发者工具,点进网络标签,重新刷新网站,有js文件就是动态网站 参考技术C 这个一那个应该是动态网页的

Selenium:在动态加载网页中滚动到页面末尾

【中文标题】Selenium:在动态加载网页中滚动到页面末尾【英文标题】:Selenium: Scroll to end of page in dynamically loading webpage 【发布时间】:2018-07-28 18:59:35 【问题描述】:

我的网页在向下滚动页面时会不断加载新项目,直到所有项目都加载完毕。

我正在使用 Java 中的 Selenium,需要向下滚动到页面底部才能加载所有内容。

我尝试了几种不同的选项,比如滚动到页面底部的某个元素:

WebElement copyrightAtEndOfPage = webDriver.findElement(By.xpath("//a[@href='/utils/copyright.html']"));
((JavascriptExecutor) webDriver).executeScript("arguments[0].scrollIntoView();", copyrightAtEndOfPage);

这只是向下滚动一次,然后网页继续加载。

我也尝试了this 方法,它也只向下滚动一次,因为它只考虑浏览器高度。

非常感谢任何帮助。

【问题讨论】:

我们也可以用JS做类似的事情吗? 【参考方案1】:

我将为此提供 Python 代码。我认为翻译成 Java 很容易:

def scroll_down(self):
    """A method for scrolling the page."""

    # Get scroll height.
    last_height = self.driver.execute_script("return document.body.scrollHeight")

    while True:

        # Scroll down to the bottom.
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        # Wait to load the page.
        time.sleep(2)

        # Calculate new scroll height and compare with last scroll height.
        new_height = self.driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:

            break

        last_height = new_height

希望对你有帮助!

【讨论】:

效果很好,非常感谢!我还将用我翻译成 Java 的代码发布答案。 做到了。再次感谢! 嘿..感谢您的回答..这也应该帮助我!只是一个查询,当我使用这段代码时,我的浏览器会滚动到最后,但新元素仍然没有被捕获。我对此有点陌生。我正在使用 driver.get(url) 后跟上面的代码..你能帮忙吗? @ShrutiJoshi,当您调用此函数时,此代码只会向下滚动到可见页面(屏幕上)的底部。【参考方案2】:

感谢 Ratmir Asanov(请参阅上面批准的答案),我将 Python 代码翻译成 Java,以便其他人更容易实现。

try 
    long lastHeight = (long) ((JavascriptExecutor) webDriver).executeScript("return document.body.scrollHeight");

    while (true) 
        ((JavascriptExecutor) webDriver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
        Thread.sleep(2000);

        long newHeight = (long) ((JavascriptExecutor) webDriver).executeScript("return document.body.scrollHeight");
        if (newHeight == lastHeight) 
            break;
        
        lastHeight = newHeight;
    
 catch (InterruptedException e) 
    e.printStackTrace();

【讨论】:

【参考方案3】:

稍微更新了 Johannes 代码以使其正常运行。

JavascriptExecutor js = (JavascriptExecutor) driver;
try 
    long lastHeight=((Number)js.executeScript("return document.body.scrollHeight")).longValue();
    while (true) 
        ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
        Thread.sleep(2000);

        long newHeight = ((Number)js.executeScript("return document.body.scrollHeight")).longValue();
        if (newHeight == lastHeight) 
            break;
        
        lastHeight = newHeight;
    
 catch (InterruptedException e) 
    e.printStackTrace();

【讨论】:

类型转换是问题,它抛出编译错误。 错误是什么?因为我从未遇到过该代码的任何问题,并且我在我的项目中以 1:1 的比例使用它。【参考方案4】:

Prabhat 进一步更新上述解决方案,因为它仍然给我编译错误。

    try 
        Object lastHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");

        while (true) 
            ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
            Thread.sleep(2000);

            Object newHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
            if (newHeight.equals(lastHeight)) 
                break;
            
            lastHeight = newHeight;
        
     catch (InterruptedException e) 
        e.printStackTrace();
    

【讨论】:

【参考方案5】:

我找到了另一个动态加载页面的解决方案。

计算每次滚动前后显示的元素,并比较它们以确定您是否已滚动到底部。

var reachedEnd = false;
oldCount = driver.FindElements(By.CssSelector(".searchDataContainer.table-row.raw")).Count;

while (!reachedEnd)

    driver.FindElement(By.CssSelector("body")).SendKeys(Keys.End);
    Thread.Sleep(500);
    oldCount = driver.FindElements(By.CssSelector(".searchDataContainer.table-row.raw")).Count;

    if (newCount == oldCount)
    
        reachedEnd = true;
    
    else
    
        newCount = oldCount;
    

【讨论】:

【参考方案6】:

更新了对我有用的代码:

try 
                    long lastHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                    int cont=1000;
                    while (true) 
                        ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, "+cont+");");
                        Thread.sleep(2000);

                        long newHeight = (long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                        if (newHeight <= cont) 
                            break;
                        
//                      lastHeight = newHeight;
                        cont+=500;
                    
                 catch (InterruptedException e) 
                    e.printStackTrace();
                

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于selenium官网是动态网页吗的主要内容,如果未能解决你的问题,请参考以下文章

为采集动态网页安装和测试Python Selenium库

python爬虫-27-python之Selenium入门,动态网页抓取

爬虫---selenium动态网页数据抓取

使用scrapy-selenium, chrome-headless抓取动态网页

使用 selenium 从动态网页表中查找值

Selenium:在动态加载网页中滚动到页面末尾