selenium + Beautifulsoup 爬虫技术及踩坑经验

Selenium简介

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器。

BeautifulSoup简介

Beautiful Soup支持各种html解析器,包括python自带的标准库,还有其他的许多第三方库模块。其中一个就是lxml parser。
借助网页的结构和属性等特性来解析网页的工具,有了它我们不用再去写一些复杂的正则,只需要简单的几条语句就可以完成网页中某个元素的提取。

selenium + Beautifulsoup 爬取网易健康医疗数据

一、项目介绍

1.1 爬取网址与内容
网址:http://jiankang.163.com/special/search/?f_id=1&s_id=&page=
爬取内容:根据每一个科室把疾病详情,爬取存入excel数据库
在这里插入图片描述
如中暑的七个疾病详情
在这里插入图片描述

1.2技术分析
此网站不同于一般的html站点,html站点每一个页面的button对应的url都可以通过request得到,同时可以将页面源码存储为text,接着通过正则表达式就可以对应url和需要的信息比较容易。
而此网站使用了javascrip的异步加载,这样是不同于一个静态网站,这种类型网站的url和重点信息是不能通过inspect查看到的,并且get到的页面不会包含源码全部信息,因为它是动态的时刻都在变化。
根据这种变化,可以直接用模拟浏览器操作,在pycham中安装selenium库,驱动chromedriver,以此动态的加载数据,同时再用BeautiSoup库分析页面,最后爬取所需要的数据。

二、项目构建

2.1项目流程
创建chrome对象得到第一页html内容
在这里插入图片描述
通过BeautifulSoup创建第一url内容对象,使用lxml解析方式
在这里插入图片描述
通过soup.select()确定每一个科室button的tag
在这里插入图片描述
获得除了第一个科室以外的每个科室的url
在这里插入图片描述
进入每一个科室的页面后的,爬取所有数据一定要翻页,(因为采用的是异步加载,翻页的‘下一页’的path每一个都不同,这样就不能直接soup获取‘下一页’的button的url然后click)这里我是寻找每一个科室不同页面url之间的规律,最后发现每一页只用最后的‘page=n’最后的数字不同,这样就好办了,一个科室有多少页疾病,就用for循环几页,而要达到这样的目的就需要把页数提前记录下来如下:
在这里插入图片描述
在这里插入图片描述

current_number对应第几个科室,next_url即下一页页面url,str(i+1)为更改url后面的page=n中的n的,从而实现跳到下一页的目的。这样每个科室的每一页疾病就能够看到了
在这里插入图片描述
接下来分析每一页的疾病,利用soup解析当前页面,获得页面每个疾病的url
在这里插入图片描述
进入疾病详情页,再利用soup解析页面,获取疾病详情,存入excel
在这里插入图片描述
注意用web获得页面和获取页面资源之间要停留一段时间,不然爬取数据不全(可能是因为时间太快,来不及存储信息?)最后注意的是用for in 语句
存入信息,如果把每个疾病对应的各个不同相关属性用disease_infom[n]的形式write会报错,具体原因有待探究。最后储存文件。
在这里插入图片描述
2.2项目代码

from selenium.webdriver import Chrome
from bs4 import BeautifulSoup
import time
import lxml
import xlwt
f = xlwt.Workbook()
sheet1 = f.add_sheet(u'就诊指南', cell_overwrite_ok=True)
a = ['科室', '疾病名称', '简介', '症状', '病因', '预防', '检查', '治疗', '护理', '并发症']
# 每个科室对应的页面数
pages = [1, 28, 19, 6, 4, 2, 3, 4, 1, 2, 1, 3, 1, 1, 7, 6, 2]
for i in range(0, 10):
    sheet1.write(0, i, a[i])
web = Chrome()
web.get("http://jiankang.163.com/special/search/?f_id=1&s_id=&page=")
web_urls = web.find_elements_by_xpath('//*[@id="main_article_ul"]/li/h3/span/a')
# print(web_urls)
# web.switch_to.window(web.window_handles[-1])
# 找到所有科室url
web_data = web.page_source
soup = BeautifulSoup(web_data, 'lxml')
infoms = soup.select('#pc_list_keshi_s_id > li > a')
# 当前科室数
current_department_num = 0
row = 1
n = 1
for info in infoms:
    # 访问第一个科室,科室数为1
    current_department_page = 1
    if info.string == '不限':
        continue
    # 找到标签里的href,并转到
    web.get(info['href'])
    web.switch_to.window(web.window_handles[-1])
    # 当前页疾病列表
    #diseases_urls = web.find_elements_by_xpath('//*[@id="main_article_ul"]/li/h3/span/a')
    # 设置跳页,及访问下一页
    for i in range(0, pages[current_department_num]):
    # 得到当前页url
        next_url = info['href'] + str(i+1)
        print(next_url)
        web.get(next_url)
        next_data = web.page_source
        next_soup = BeautifulSoup(next_data, 'lxml')
        # diseases_url = web.find_elements_by_xpath('//*[@id="main_article_ul"]/li/h3/span/a')
        diseases_url = next_soup.select('#main_article_ul > li > h3 > span > a')
        for disease_url in diseases_url:
            # disease_url.click()
            print(disease_url['href'], disease_url.string, n)
            n = n + 1
            # web.switch_to.window(web.window_handles[-1])
            web.get(disease_url['href'])
            time.sleep(2)
            disease_page = web.page_source
            disease_soup = BeautifulSoup(disease_page, 'lxml')
            disease_infoms = disease_soup.find_all(class_='jbxq_desc')
            # disease_navs = disease_soup.find_all(class_='jbxq_nav')
            #for info_num in range(0, len(disease_navs)):
            # 存入科室
            sheet1.write(row, 0, info.string)
            # 存入疾病名称
            sheet1.write(row, 1, disease_url.string)
            # 存入疾病信息
            col = 2
            for disease_infom in disease_infoms:
                sheet1.write(row, col, disease_infom.text)
                col = col + 1
            row = row + 1

    current_department_num = current_department_num+1
    # 跳页
f.save(r"C:\\Users\Administrator\Desktop\疾病百科_2.xls")

三、总结
Selennium + bs4 可以爬取多数网站,bs4作为一个解析网站的工具,利用好bs4可以不用费时的写一些正则表达式。而使用selenium可以驱动浏览器,加载页面全部内容,是神器。
一些坑:
1.安装库:pip时可以选择国内镜像源源,如
(1)豆瓣 http://pypi.douban.com/simple/
(2)清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
(3)阿里云 http://mirrors.aliyun.com/pypi/simple/
(4)中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
(5)华中科技大学 http://pypi.hustunique.com/
安装命令

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4

若出现run timeout 设置默认时间(时间可更改,此处设为100)

pip --default-timeout=100 install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4

2.如果爬取需要点击下一页的代码,不能直接用soup.select()出一个下一页这个button重复使用,如果想selcet‘下一页’的button,应该用一个for循环,每访问一个页面更新下一个‘下一页’bttton。或者用我的方法更新每个page的url
3.元素类型为text的列表,不宜用a[i]的形式write()文件,应该用for循环。
4.web.get 和web.page_source之间利用sleep或许会增加数据的完整度,没有sleep时爬取的数据不完整,每一页大概7条数据只能爬两条,加了语句,能爬。
5.windows下适合安装豆瓣源头,linux下适合安装清华源头,当出现pip无法安装的问题,很可能时源的原因
6.可以尝试修改pip.ini解决
在这里插入图片描述
7.如果pip安装了包,显示在了anaconda下的site-packages但是无法import,可以先激活环境,后使用conda install pip在anaconda的环境下安装pip,这样又能重新安装包,而且包也能安装在anacodna下。

selenium优秀博客

国内源数据来源

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值