学了一个月了,总感觉需要做一个全站爬取才能更好的巩固这些零散的知识。不过找也没敢找太难的,天猫、京东这些想爬全站,我还做不到。最后我选择了微医这个网站。
想做一件事,第一步必不可少的就是需求分析。
对于医生我需要获取的数据是
- 姓名
- 职位
- 评分
- 预约量
- 问诊量
- 关注
- 所属医院科室
- 患者印象
- 来访医院(可以看到所属医院里面就诊总数)
- 来源(可以看到线上就诊线下就诊)
- 专治(医生涉及领域)
对于患者我想获取的数据是
- 医生满意度
- 评论
- 时间
- 就诊来源
- 疾病
这是首页图

基本框架

通过分析发现
- 一个主科室包括2到3个副科室
- 点击主科室显示全部副科室(不碰不会显示)
- 最后还有其他科室
- 点击疾病后才能显示医生数据
- 这里需要解决触碰主科室的实现,以便获取全部副科室的数据
- 获取疾病URL后需要添加expert字符,来获取更多医生
这里我分为第一步,获取全部疾病的URL

第二步,就要把这些URL放在分布式里运行了,总共12万医生(基于docker容器)

分布式这里我使用了用户代理和IP代理,并且对他们做了限制,因为在分布式里要能正确运行
IP:
1------>正在使用
2------>损坏IP
空------>未使用
3------->未使用
URL:
1---->正在尝试爬
2---->爬取完成
空--->未爬
3---->未爬
有了这些控制,所有节点就能很好的把全部连接全部爬完,并且IP还不一样。

我准备了10个从节点一个主节点。主节点只负责发数据和存储数据,从节点负责获取数据发送数据。
之所以使用redis,是因为它速度快,当时用的时候也是刚接触,并不了解。
最后待爬取完成,会获取医生的信息和医生涉及领域的评价url。接下来就该获取医生评价信息。(这里的医生信息和评价信息通过医生ID进行连接)

对于评价信息。这个网站设置了反爬,会跳出极验的滑动验证码。我尝试一下不成功,就想了用多进程+redis+selenium来尽量的减少爬取时间。
这里需要说一下评价URL的翻页逻辑,因为不弄懂怎么翻页,是不能爬取全站信息的。
对于翻页代码,我是这样做的
fl=1 while(True): if(i==1 and fl!=1): i=5 elif(i==5 and fl!=1): i=6 elif(b==1 and fl!=1): i=6 b=2 elif(i==6 and fl!=1): i=7 elif(i==7 and fl!=1): i=8 if(fl!=1): try: js='window.scrollTo('+str(0*1080)+','+str((1)*1080)+')' a="/html/body/div[1]/div[2]/div/div[2]/div/section/div[2]/div[3]/div/form/div[1]/a["+str(i)+"]" browser.execute_script(js) browser.find_element_by_xpath(a).click() except Exception as err: break fl=2
这个翻页看似没规律,其实还是有规律的。
这些准备完,就可以运行了。
由于时间原因,评价数据我还没有进行清洗。得到还是我给它设置的格式。

当数据到手之后我发现并不理想,首先我并没有做过全站爬取,练手的时候都是爬几页玩玩,这些数据有很多我没有考虑到,也有一些是我代码不规范造造成的,毕竟python刚学就接触爬虫去了,对异常处理的不好,以及爬的数据本身也有热度的一些问题。导致出现了很多空数据,乱的数据。最后通过numpy和pandas现学现用的,最终才筛选出了干净的数据。当然了,脏数据很多,不过已经没用了,还是自己不行,下次考虑全面一些会好点。