记录使用Selenium抓取前端渲染数据

这几天准备用程序抓下一个网站的数据, 具体哪个就不说了, 为了减少人工劳动, 省点力气。用到的技术 Java, Selenium, chromeDriver, 系统ubuntu16.04

开始查看了网站的源码, 看到网站使用的模板的方式,

<% for(var i=0; i < loop_times; i++) { %>
    <% var items = rider_list.slice(i * num_per_line, (i+1) * num_per_line); %>
    <tr>
      <% for (var j=0; j < items.length; j++) { %>
        <%

这样直接抓取html是无法拿到数据的,页面展示的内容是经过浏览器渲染过之后的结果, so。。。, 需要使用浏览器把拉下的源码执行js脚本,前端渲染出页面, 再使用xpath 解析数据。

Selenium可以通过WebDriver调用Chrome 、Firefox 、Safari 等浏览器。

WebDriver 支持以下的

  • ChromeDriver
  • EventFiringWebDriver
  • FirefoxDriver
  • HtmlUnitDriver
  • InternetExplorerDriver
  • PhantomJSDriver
  • RemoteWebDriver
  • SafariDriver

chromeDriver 下载地址: https://sites.google.com/a/chromium.org/chromedriver/downloads ,注意版本支持情况, 我用的是最新的版本2.37

Latest Release: ChromeDriver 2.37
Supports Chrome v64-66

安装 Google Chrome 这里我们选择的是 google-chrome-stable 版本:

$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install google-chrome-stable

测试chromeDriver 是是否正常运行, 最初阿里云的ECS安装的是centos6.8 的系统, 安装完linux chrome, 运行chromeDriver的时候,遇到各种库找不到,根据提示一直装下去, 还是问题不断, 谷哥发现说centos 对chrome 支持不太好(没有继续跟踪原因, 有懂的朋友给明示一下,多谢), 换成ubuntu 16.04, 测试正常

root@iZj6c1imv6wpn7tfmm7nusZ:/work/fantasy# ./chromedriver
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 9515
Only local connections are allowed.

抓取页面的java代码, 使用chromeDriver 渲染后可以正常的使用 xpath, 查找html元素了, 基础的用法就是使用By 的查找方式了, 可以按id, class, tag等等查找

这里有几个点需要注意


            ChromeOptions options = new ChromeOptions();

            options.addArguments("--headless");
            options.addArguments("--disable-gpu");
            options.addArguments("--no-sandbox");

option 需要设置,

  • headless Chrome指在headless模式下运行谷歌浏览器。本质就是不用谷歌运行谷歌!它将由Chromium和Blink渲染引擎提供的所有现代网页平台的特征都转化成了命令行。 必须在59以后可以使用
  • disable-gpu, 服务器很多没有gpu, 禁用掉,防止出错
  • no-sandbox 取消沙盒模式, 在root用户下, 必须加上此选项

准备工作已做好, 可以抓到数据了, 摆脱人工定时查看, 可以使用bearychat ,出现需要通知的给自己或者团队发送消息通知, 做幸福的程序员

java 抓取分析代码

    private WebDriver           webDriver;

    public XXXSpider() {

        String driver = System.getProperty("webdriver.chrome.driver");

        if (driver == null) {
            logger.info("没有设置 driver 变量");
            System.getProperties().setProperty("webdriver.chrome.driver", "/Users/chengpanwang/Downloads/chromedriver");
        } else {
            logger.info("driver: {}", driver);
        }

    }

    public BigDecimal pageDetail(String url) {
        logger.info("详情页: {}", url);

        ........

        try {

            ChromeOptions options = new ChromeOptions();

            options.addArguments("--headless");
            options.addArguments("--disable-gpu");
            options.addArguments("--no-sandbox");

            webDriver = new ChromeDriver(options);

            webDriver.get(url);

            WebElement webElement = webDriver.findElement(By.xpath("/html"));
            WebElement roleSkill = webElement.findElement(By.id("role_skill"));
            logger.info(roleSkill.getText());
            logger.info("选中技术标签");
            roleSkill.click();

            WebElement skillTb = webElement.findElement(By.className("skillTb"));

            for (WebElement item : skillTb.findElements(By.tagName("td"))) {
                String level = item.findElement(By.tagName("p")).getText();
                String h5 = item.findElement(By.tagName("h5")).getText();
               .... 具体业务代码
            }

            webDriver.close();
        } catch (Exception e) {
            logger.error("", e);
        }

        return price;
    }

05-04 14:51