企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 前言 上次我们使用`nightmare`这款自动化测试工具进行了百度图片关键词查询结果的爬虫,效率略低. 现在我们尝试其他的方式,更高效的进行爬虫操作.这里使用的`npm`包主要有: * axios * cheerio //本次没有用到 * mysql //我们需要把数据记录下来 * log4js //提供一个清晰的日志跟踪 ### 环境准备 * 安装MySQL,搭建本地数据库 * 安装上述模块 * 配置log4js,这里不详述具体的配置方法 * 准备数据库操作的模块,这里也不详述 ### 开始 这次我们爬取的目的,依然是百度图库,关键字查找. #### 调研 首先,确认了目前百度图片关键字查找后,图片采用滚动懒加载的方式,所以切换到`network`, ![](images/screenshot_1510299953339.png) 简单分析下: * 懒加载使用`get`方式 * 请求头连接是`https://image.baidu.com/search/acjson` * request参数我们去除空无效非关键的字段,应当如下: ```js { tn: 'resultjson_com',//这个参数不能少 ipn: 'rj',//这个参数也不能少 queryWord: '',//查询关键词 word:'',//查询关键词 pn: 30,//这个是当前页的数量 rn: 30//这个是每页的大小 } ``` * 然后response的结构大概是这样的: ![](images/screenshot_1510300490490.png) * data里是个数组,我们关心的是data内,子项的数据结构: ![](images/screenshot_1510300679440.png) 里面有很多数据,我们目前只关心图片url和图片来源的网站,分别是`thumbURL`,`fromURLHost` #### axios发送请求 ```js let pageNum = config.page.num, pageSize = config.page.size; let imageList = new Set(), hostList = new Set(); ``` ```js const getImageByPage = async(page) => { return axios.get('https://image.baidu.com/search/acjson', { params: { tn: 'resultjson_com', ipn: 'rj', queryWord: config.keywords, word: config.keywords, pn: page, rn: pageSize } }).then(response => { logger.info(`请求成功,开始解析数据,当前是第${page}页......`); let resData = response.data, lazyData = resData.data; logger.debug(`请求成功,数据长度为${undefined == lazyData ? 0 : lazyData.length}`); if (undefined == lazyData) true; let result = []; lazyData.forEach(item => { if (undefined != item.thumbURL) { imageList.add(item.thumbURL); hostList.add(item.fromURLHost); result.push(item.thumbURL); //执行数据库插入操作 db.insert(`insert into baidu_image(host,url) values("${item.fromURLHost}","${item.thumbURL}")`); } }); return true; }).catch(e => { logger.error(e.message); return false; }); } ``` ### 控制请求数量 ```js const run = async() => { //发送一个请求 for (let i = 0; i < config.page.times; i++) { logger.debug(`开始第${i+1}次请求`) if (await getImageByPage(pageNum)) { pageNum += pageSize; } else { logger.debug('没有了,终止循环'); break; } } logger.debug(`一共获取到${imageList.size}张图片`); } ``` #### 结果 ![](images/screenshot_1510300977323.png) <p class="over">Over!</p>