制作爬虫目的
由于师兄要求我查询十几个二维材料的所有禁带宽度、点阵常数,当我打开materialsProject网站,查找某个元素后,发现每个二维材料因为空间群的结构不同,也会有不同的禁带宽度和点阵常数。细数下如果要收集这些数据可能要打开一百多个网页,然后复制粘贴那些数值,为了解放机械性工作,所以凭借课余所学做了一个爬虫,来对这些数据抓取并打印下来。
了解网站,知道数据源文件的uri
首先打开该网站materialsproject,用“开发者工具进”行页面分析。搜索GaN,发现uri中包含了#符号,上网了解http不会请求#以后的数据,(关于http中带#号的介绍,可看https://blog.csdn.net/luka2008/article/details/38753269)。然后在分析中发现了一个uri是在点击“search”按钮后传回来的json文本,因此可以通过分析这个json文件的uri,来抓取相关数据,返回json文本的uri为
https://materialsproject.org/apps/materials_explorer/results?query=%7B%22reduced_cell_formula%22%3A%22GaN%22%7D 改其中红字上的内容,就可以获得想搜索的内容了
搜索结果的页面如下:
图中红色框框里面的内容是我想获取的,因此解析json文件,将material_id和其值放到map对象的键值对中,再把每个map对象通过push()放到mapList数组中。
当点击上图的列表中的其中一行,会跳转到该id值材料的详细页面中,这时通过分析页面会发现也会收到一个json文件,是关于晶格常数的。其uri为通过上述方法,把所需数据放到数组中,当请求完网页后便可以将数据一一打印出来。
爬虫操作方法:通过node运行文件后,在控制台中输入所有想操作的分子式,以空格分开,回车后便运行,并且打印出自己想要的数据,成功避免一次流水线任务,haha...
实现原理:
- 此爬虫使用nodejs实现的,用到了‘request-promise’模块以方便用async/await方法来等待收据接收完再放入数组并打印出来。
- 在控制台输入的各个分子式在通过‘line’事件被监听后,会被放入到formulaArray数组中。然后通过遍历每个分子式,分别进行json文件请求
- 在getValue()方法中,option对象的键值对是copy“开发者工具”分析页面时上的数据的,请求该uri,解析json文件,并把需要的数据放到map对象中,再把map对象填入mapList数组里面
- 然后再通过访问数组对象中材料id获取第二个json文件,其中其晶格参数有ICSD(无机晶体学数据库)的也有computed的,这里优先选取ICSD的,若ICSD不存在,再选取后者的。
- 最后通过遍历数组的对象,遍历对象的键值对,把其打印出来
爬虫代码
- const rp=require('request-promise');
- let mapList=[];//存放map对象的数组
- const readLine=require('readline');
- const rl=readLine.createInterface({
- input:process.stdin,
- output:process.stdout
- });
- rl.on('line',async function(line){
- let formulaArray=[];//存放分子式的数组
- if (line.trim()) {
- formulaArray=line.split(' ');
- for(let index=0;index<formulaArray.length;index++){ //遍历每个分子式
- await getValue(formulaArray[index]);//请求网页并存储map于mapList数组中
- } </