ajax抓取网页内容(越来越多的网站将Ajax用于精美的用户体验,简化它)

优采云 发布时间: 2022-01-23 23:13

  ajax抓取网页内容(越来越多的网站将Ajax用于精美的用户体验,简化它)

  今天,越来越多的网站使用 Ajax 来获得漂亮的用户体验、动态网页以及许多其他好的理由。

  搜索繁琐的 Ajax网站 可能有点棘手和痛苦,我们将看到一些技巧来简化它。

  先决条件

  在开始之前,请阅读我写的前几篇文章文章,了解如何设置您的 Java 环境并基本了解如何开始使用 HtmlUnit Java 进行网络爬取和处理身份验证。

  看完这篇文章,你应该对网络爬虫更加熟悉了。

  设置

  我们将了解在 Java 中抓取 Ajax 的第一种方法网站 是将 PhantomJS 与 Selenium 和 GhostDriver 结合使用。

  PhantomJS 是一个基于 WebKit 的无头 Web 浏览器(用于 Chrome 和 Safari)。它非常快,并且可以像普通的网络浏览器一样呈现 Dom。

  

com.github.detro

phantomjsdriver

1.2.0

  还有这个:

  

org.seleniumhq.selenium

selenium-java

2.53.1

  PhantomJS 和 Selenium

  我们现在将使用 Selenium 和 GhostDriver “试点” PhantomJS。

  我们将要看到的示例是新闻网站上的一个简单的“查看更多”按钮,它执行 ajax 调用以加载更多新闻。

  所以你可能认为打开 PhantomJS 来点击一个简单的按钮是浪费时间和大量时间?当然!

  新闻网站是:简而言之

  

  与往常一样,我们必须打开 Chrome 开发工具或您最喜欢的检查器,以查看如何选择“加载更多”按钮并单击它。

  

  现在让我们看一些代码:

  private static String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" ;

private static DesiredCapabilities desiredCaps ;

private static WebDriver driver ;

public static void initPhantomJS (){

desiredCaps = new DesiredCapabilities ();

desiredCaps . setJavascriptEnabled ( true );

desiredCaps . setCapability ( "takesScreenshot" , false );

desiredCaps . setCapability ( PhantomJSDriverService . PHANTOMJS_EXECUTABLE_PATH_PROPERTY , "/usr/local/bin/phantomjs" );

desiredCaps . setCapability ( PhantomJSDriverService . PHANTOMJS_PAGE_CUSTOMHEADERS_PREFIX + "User-Agent" , USER_AGENT );

ArrayList cliArgsCap = new ArrayList ();

cliArgsCap . add ( "--web-security=false" );

cliArgsCap . add ( "--ssl-protocol=any" );

cliArgsCap . add ( "--ignore-ssl-errors=true" );

cliArgsCap . add ( "--webdriver-loglevel=ERROR" );

desiredCaps . setCapability ( PhantomJSDriverService . PHANTOMJS_CLI_ARGS , cliArgsCap );

driver = new PhantomJSDriver ( desiredCaps );

driver . manage (). window (). setSize ( new Dimension ( 1920 , 1080 ));

}

  设置 phantomJs 和 Selenium 的大量代码!

  我建议阅读文档以了解可以传递给 PhantomJS 的许多参数。

  请注意,您必须将 /usr/local/bin/phantomjs 替换为您自己的 phantomJs 可执行文件路径

  然后在main方法中:

   System . setProperty ( "phantomjs.page.settings.userAgent" , USER_AGENT );

String baseUrl = "https://www.inshorts.com/en/read" ;

initPhantomJS ();

driver . get ( baseUrl ) ;

int nbArticlesBefore = driver . findElements ( By . xpath ( "//div[@class='card-stack']/div" )). size ();

driver . findElement ( By . id ( "load-more-btn" )). click ();

// We wait for the ajax call to fire and to load the response into the page

Thread . sleep ( 800 );

int nbArticlesAfter = driver . findElements ( By . xpath ( "//div[@class='card-stack']/div" )). size ();

System . out . println ( String . format ( "Initial articles : %s Articles after clicking : %s" , nbArticlesBefore , nbArticlesAfter ));

  这里我们调用 initPhantomJs() 方法来设置所有内容,然后选择带有 ID 的按钮并单击它。

  代码的另一部分计算页面上已经存在的 文章 的数量,并将其打印出来以显示我们已加载的内容。

  我们也可以使用driver.getPageSource()打印整个dom,在真实浏览器中打开,看看点击前后的区别。

  我建议你看看 Selenium Webdriver 文档,有很多很酷的方式来操作 DOM。

  我对 Thread.sleep(800) 使用了一个肮脏的解决方案来等待 Ajax 调用完成。

  它很脏,因为它是一个任意数字,如果我们只等待执行该 ajax 调用所需的时间,scraper 可以运行得更快。

  还有其他方法可以解决这个问题:

  public static void waitForAjax ( WebDriver driver ) {

new WebDriverWait ( driver , 180 ). until ( new ExpectedCondition () {

public Boolean apply ( WebDriver driver ) {

JavascriptExecutor js = ( JavascriptExecutor ) driver ;

return ( Boolean ) js . executeScript ( "return jQuery.active == 0" );

}

});

}

  如果您查看单击按钮时正在执行的函数,您会发现它正在使用 jQuery:

  

  这段代码会一直等到变量 jQuery.active 等于 0(这似乎是 jQuery 的一个内部变量,用于计算正在进行的 ajax 调用次数)

  如果我们知道 Ajax 调用应该渲染哪些 DOM 元素,我们可以在 WebDriverWait 条件中使用该 id/class/xpath:

  wait . until ( ExpectedConditions . elementToBeClickable ( By . xpath ( xpathExpression )))

  结论

  所以,我们已经了解了如何在 Java 中使用 PhantomJS。

  我给出的例子很简单,模拟一个请求很容易。

  但有时当您有几十个 Ajax 调用,并执行大量 Javascript 以正确呈现页面时,很难抓取您需要的数据,PhantomJS/Selenium 将您保存在这里 :)

  下一次,我们将通过分析 AJAX 调用并自己发出请求来了解如何做到这一点。

  与往常一样,您可以在我的 Github 存储库中找到所有代码

  *敏*感*词*渲染 JS 真的很困难而且很昂贵。这就是我们构建 ScrapingBee 的原因,它是一个网络抓取 API,可以为您处理这些问题。

  它还会使用代理和验证码,不要犹豫,前 1000 个 API 调用即将到来。

  发件人:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线