最近将万方数据的爬取代码进行了重构,速度大概有10w每小时吧,由于属于公司项目,代码暂时就不开源了,因此在这里先说说思路和一些注意事项吧,顺带吐槽一下万方。html
先上图:redis
其实逻辑也蛮简单的,医学类的期刊分了16个大类,那么首先手动将这16大类所对应的惟一id拿下来拼接出该类型的url,而后翻页请求它就能够得到该类型下的每一篇期刊的信息。json
而后咱们拿到了每一个期刊的id,就能够拼接出每个期刊的主页url,可是这时就会发现,万方中的期刊主页路由是有两套的:我将其称之为新版/老版微信
新版:http://www.wanfangdata.com.cn/sns/user/qkzgf4cookie
老版:http://www.wanfangdata.com.cn/perio/detail.do?perio_id=zgjhmyurl
这两个版本的url是不一样的,那么如何甄别那一篇期刊是新版仍是老版呢?毕竟咱们如今只知道期刊的id,这里我用的办法是默认将每一篇期刊均视为老版,而后利用期刊id拼接出老版的url,代理
若是这篇期刊真是老版,那么就能够请求到期刊主页,若是它是新版,那么他就会被重定向到新版主页,最终咱们只须要观察它的response.url就清楚了。code
为何说要分辨期刊属于新版仍是老版呢,觉得关系到下一步请求该期刊中全部文章的问题。orm
由于万方中每个期刊都是规则的,有一个时间树,代表这篇文章属于哪一个期刊、哪一年、哪一期,因此咱们想要获取这个期刊中的全部文章,首先就须要解析这个期刊的时间树,可是新版和老版时间树是不同的。htm
看图:
看到没,这就是上一步咱们要来辨别期刊是新版仍是老版的缘由了。
既然知道了期刊是新版仍是老版,那么下一步咱们就须要来请求时间树以得到这个期刊的全部年份和每年有多少期,觉得下一步请求文章内须要用到这些信息。
原本请求到时间树再进行解析,拿到有用信息后根据每一期每一期的请来求文章json应该是美滋滋的事情,可是获得的反馈却并不怎么好,由于我发现最终请求到的文章只有不多一部分,其余的都请求不到,返回空json,
我百思不得其解,而后就各类开始捣鼓,像什么换代理啊,换UA啊,加cookie啊是一顿操做,结果是一顿操做猛如虎,一看结果250,这就很尴尬,最终折腾了很久终于被我发现了问题得关键所在,那就是这个:
看到没,时间树解析下来2019年共出了7期文章,给的是01,02直到07, 可是在请求时倒是 1到 7,0没了。。。因此致使请求的结果都是空的。
但即便是这样,在请求每一期文章时还会有问题,只是这个问题只在老版本中出现,那就是在解析时间树后一期一期请求文章,按理说请求的结果都会是一个json,
可是在老版本这儿会是否是返回一个html,致使我程序报错,由于我都是将返回结果按照json来处理的,直到如今我都没搞明白为何回忽然不返回json而返回html,我猜应该是请求过快了吧。
因此我多加了一部处理,当发现返回的不是json时就将这个期刊的id+年份+期数放到redis中,而后另起一个job来从redis中将其取出来再此进行请求,请求到json就其从set中去除,否则就又将其放到set中,循环请求。
这样最终再解析请求到的这一期的文章json就获得文章内容了,文章的做者信息也在这个json中。
这就是整个流程了。 接下来是吐槽环节:
不得不说万方真的是太爱改版了,最开始叫万方医学,后来改成了万方数据,而后好巧不巧在我此次采集期间又又又改版了,并且被我当场发现了,而且从中发现了一个接口:
http://www.wanfangdata.com.cn/perio/page.do
这个接口是在万方改版期间出现的,改版前没有,改版后也没有,就只出现了一小会儿,如今网页中是看不到它的
这个接口是用来请求那16个大类中又哪些期刊的,返回的json中包含了各个期刊的全部信息,比期刊主页展现的信息要全的多,而且有两点对个人工做有了很大的帮助,自己每一个期刊的时间树都是要请求一次的,这样无疑会拖慢爬虫的速度,并且会出现请求不到的状况,在这个接口中却包含了期刊的时间树,还有一个就是自己想要获取这个期刊的影响因子的话,是须要请求期刊主页来解析页面的,如今也不用了,json中也有了,省了很多事儿,可是这个接口是不在万方官网中显示的,说明他们如今展现时用的不是这个接口,当初只是临时用了一下子,之后会不会消失,不清楚。
这是请求这个接口的formdata: (code_name是那16大类的惟一标识)
最后,打个广告: 想了解更多Python关于爬虫、数据分析的内容,获取大量爬虫爬取到的源数据,欢迎你们关注个人微信公众号:悟道Python