记录一次失败的数据抓取之Puppeteer

栏目: Node.js · 发布时间: 6年前

内容简介:前段时间女朋友需要统计一部分公司的办公地点,但由于公司非常多,自己一个一个查很明显不靠谱。于是就想是不是可以用什么方式抓数据呢?理所当然的想到了Python,可惜不会写,所以放弃了。再后来就在GitHub上看到了这个项目Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by

前段时间女朋友需要统计一部分公司的办公地点,但由于公司非常多,自己一个一个查很明显不靠谱。于是就想是不是可以用什么方式抓数据呢?理所当然的想到了Python,可惜不会写,所以放弃了。再后来就在GitHub上看到了这个项目 Puppeteer ,做了一次数据抓取的尝试,本来想秀一把,结果秀的不好,翻车了,但好在见识到了Puppeteer的魅力。

介绍

Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.

一言以概之就是chrome浏览器能干的事情,Puppeteer基本都能做到。

其它的抓取方式大部分可能是分析接口然后通过接口调用获取相应的数据,而Puppeteer是像人一样正常访问相应网站然后读取/修改/操作相应的网页内容。

简单总结了一下在我这次使用Puppeteer发现的优缺点:

优点:

  • 上手很容易
  • API足够的简单完善
  • 由于可以在访问、输入等方面做到拟人的操作,被检测的风险略低

缺点:

  • 由于和用户操作类似,需要加载网页相关资源,所以相对来说比较慢

准备工具

企业名称的excel

npm包:Puppeteer、node-xlsx

node环境:推荐高版本 Node 可以使用 async/await 语法

抓取对象:天x查

抓取分析

1.利用企业名称进行搜索

2.获取搜索列表第一条数据中的id

3.跳转到详情页

4.获取页面上详细地址一栏的数据

由于测试过程中发现,连续几次操作后进入详情页需要登陆,所以在最开始加入了登陆的流程。

抓取实现

有了上面的结论后可以使用 Puppeteer 进行模拟访问了

const puppeteer = require('puppeteer');

(async () => {

    // 打开浏览器以及一个页面
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    // 跳转到登陆页
    await page.goto('https://www.tianyancha.com/login');

    // 模拟输入用户名和密码
    await page.type('.modulein1 input.contactphone', '手机号');
    await page.type('.modulein1 input.contactword', '密码');

    // 模拟点击登陆
    await page.click('.modulein1 .login_btn');
    // 等待页面加载完成,以保证登陆成功
    await page.waitForNavigation({
        waitUntil: 'load'
    });

    try {
        const address = await getDetailAddress('xx科技技术有限公司');
        console.log('公司地址:',address);
    } catch (e) {
        // 异常时截图用于分析错误原因
        await page.screenshot({path: "erroor.png"});
        console.error(e);
    }

    // 获取公司地址
    async function getDetailAddress(companyName) {
        // 根据公司名搜索
        await page.goto(`https://bj.tianyancha.com/search?key=${companyName}`, {
            waitUntil: 'load'
        });

        // 获取搜索结果第一条的id
        let detailIds = await page.evaluate(() => {
            // 植入js代码到网页当中,并返回结果
            return $('.search-result-single').eq(0).data('id');
        });

        // 判断id是否存在,决定是否进入详情页
        if (detailIds) {
            // 进入详情页
            await page.goto(`https://www.tianyancha.com/company/${detailIds}`, {
                waitUntil: 'load'
            });

            // 获取详情页的公司详细地址数据
            let address = await page.evaluate(() => {
                return $('.address').attr('title');
            });

            return address;
        }

        return;
    }


})();

数据转换

从详细地址中提取出省市区街道信息。

getAddressObj('北京市朝阳区阜通东大街1号院3号楼1单元2层111110')

function getAddressObj(addressStr) {
    const arr = addressStr.match(/([^省]+省|.+自治区)?([^市]+市|.+自治州)([^县]+县|[^区]+区)([^区]+区|.+镇)?(.*)/);

    if (!arr || !arr.length) {
        return {}
    }

    return {
        province: arr[1] || arr[2],
        city: arr[2],
        county: arr[3],
        town: arr[4],
        village: arr[5]
    }
}

文件操作

对比了很久在node中操作excel比较好用的插件,最后还是选用了 node-xlsx

const fs = require('fs');
const xlsx = require('node-xlsx').default;


// =======读取excel数据=======
// 读取excel文件
const workSheetsFromFile = xlsx.parse(`${__dirname}/企业名称.xlsx`);
// 获取工作表中的所有数据
let allData = workSheetsFromFile[0].data;

// =======保存结果到excel=======
let buffer = xlsx.build([{name: "企业名称地区对照表", data: [/*数据*/]}]);
fs.writeFile(`企业名字对照表.xlsx`, buffer, {
    encoding: 'utf8',
    mode: 438,
    flag: 'w'
}, function (err) {
    console.error(err);
})

总结

最后,还是失败了,为什么呢?网站会在查询100多跳数据后提示输入验证码;整体速度太慢,一条数据抓取时间在在2s左右,要想抓取上万条数据耗时太长。

虽然是失败了,但还是尝试了一把 Puppeteer 感觉这东西可以在测试/抓取等方面提供很大的帮助。后面才知道有别的组大神用 Puppeteer 监控支付宝余额,玩儿的贼6。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

软件测试的艺术

软件测试的艺术

梅尔斯 / 机械工业出版社 / 2006年01月 / 22.0

《软件测试的艺术》(原书第2版)成功、有效地进行软件测试的实用策略和技术:    基本的测试原理和策略      验收测试    程序检查和走查         安装测试    代码检查            模块(单元)测试    错误列表            测试规划与控制    同行评分            独立测试机构    黑盒、白盒测试    ......一起来看看 《软件测试的艺术》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具