Python爬虫案例:从39问医生网爬取口腔科的在线问答记录(单轮问答)

本文详细描述了如何使用Python爬虫技术,包括requests,BeautifulSoup和pandas库,从39问医生网口腔科分类下抓取100页的在线单轮问答记录,获取用户代理,解析网页结构,提取问题和答案,并将数据保存为Excel文件。
摘要由CSDN通过智能技术生成

实验内容:

本次实验爬取39问医生网中口腔科分类下的所有在线单轮问答记录,每页32条,共100页,总数据量为3200条,最终结果以excel格式保存。

开发环境:

Windows+Pycharm+Python3.9

Edge浏览器

requests库:命令行输入pip install requests

BeautifulSoup:命令行输入pip install beautifulsoup4

pandas:命令行输入pip install pandas

openpyxl:命令行输入pip install openpyxl

分析网站结构:

进入网站页面(口腔科每日最新提问和医生回复第1页_39问医生_39健康网),可以看到这是一个目录页,而要获取具体的问答内容则需要点击目录页中的超链接进行跳转。

此外,通过观察其网址我们可以发现,目录页的网址信息是与页码对应的(例如第1页就是xxx-1.html),而问答页的网址则没有什么规律(https://ask.39.net/question/_te7uy5.html),这就意味着我们需要先从目录页爬取所有问答页的URL,再借助该URL爬取我们所需要的问答记录。

目录页:

问答页:

获取User-Agent:

首先讲一下为什么要获取User-Agent。它的作用是将我们的爬虫伪装成一个用户正常的浏览器访问,否则网站就有可能会察觉到正在请求访问的是一个爬虫,从而拒绝访问。

按键盘F12进入开发者工具,或鼠标右击任一位置点击检查,即可看到网站的HTML代码,仔细观察可以发现HTML中的信息和网页中显示的内容是对应的,如图所示:

点击这里的”网络“:

之后刷新网页,可以看到下面多出很多东西:

选择第一项,在标头这里可以看到很多有用的信息,如请求的URL、请求方法、状态码等,这里我们把它拉到最下面,这个User-Agent就是我们需要用到的内容,将它复制下来。

代码实现思路:

准备工作做完了,接下来就可以尝试编写爬虫了,这里简要介绍一下思路。

首先设置好目录页的URL和请求头信息,请求头部分填入刚刚复制的User-Agent,向目录页发送request请求,并通过状态码判断请求是否成功。然后使用BeautifulSoup解析获取到的网页内容。

借助开发者工具我们可以看到,问答页的URL作为 ‘a’ 的 ‘href’ 属性藏在 <p class="p1"> 下面,所以我们首先使用soup.findAll('p', class_='p1')找到所有<p class="p1">下的父节点,遍历每一个父节点,找出name为 'a' 的子节点,提取其 ‘href’ 属性值,拼接得到问答页的URL。

接下来用类似的方法向问答页发送request请求,借助开发者工具,可知患者提问的内容是<p class="txt_ms">的文字部分,而医生的回答是<p class="sele_txt">的文字部分,所以我们可以先使用.find()找到对应节点,接下来用.get_text()获取节点的文本信息。将爬取的信息保存到事先创建好的列表中,同时计数器加一。

最后调用pandas工具包,将数据转换为DataFrame对象并保存为excel文件。

代码:

# 1 导入所需的库:requests 用于发送网络请求,BeautifulSoup 用于解析网页内容。
import requests
from bs4 import BeautifulSoup

# 2 data[]用于存储爬取的数据,count用于计数。
data = []
count = 0

# 3 设置请求头信息head,这里的'User-Agent'就是把刚刚复制的内容粘贴进来。
head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0'}

# 4 遍历从1到100页的网页
for page in range(1,101):
    url = "https://ask.39.net/news/141-" + str(page) + ".html"
    # 5 发送GET请求获取网页内容,并检查请求是否成功。
    response = requests.get(url, headers=head)
    '''
        # 状态信息,若为200则表示请求成功
        # print(response.status_code)
        # 头信息
        # print(response.headers)
        # 编码信息,解决中文乱码问题
        # print(response.encoding)
        # 查看返回的网页内容,一般为html或json形式
        # print(response.text)
    '''
    if response.status_code == 200:
        print('正在爬取第%d页' % page)
        # 6 使用BeautifulSoup解析获取到的网页内容
        soup = BeautifulSoup(response.text, 'html.parser')
        # 7 查找所有name为'p',class为'p1'的父元素
        parent_elements = soup.findAll('p', class_='p1')
        # print(parent_elements)
        # 8 遍历每个找到的父元素
        for parent in parent_elements:
            # 9 找到父元素中name为'a'的节点,提取其节点属性值
            node = parent.find('a')
            link = node['href']
            # question = node.get_text()
            # 10 拼接得到次级url,并向其发送get请求,这时返回的就是问答页面
            url_sub = "https://ask.39.net" + link
            r = requests.get(url_sub, headers=head)

            if r.status_code == 200:
                # 11 解析问答网页,查找患者提问部分和医生回答部分,将其拼接为一份完整数据,同时计数器加一
                soup_sub = BeautifulSoup(r.text, 'html.parser')
                question = soup_sub.find('p', class_='txt_ms')
                q = question.get_text().replace('\n','')      # 先去掉'\n'
                q = q.replace(' ','')       # 再去掉空格
                # print(q)
                answer = soup_sub.find('p', class_='sele_txt')
                a = answer.get_text()
                # print(a)
                count += 1
                data.append([count,q,a])
    else:
        print('爬取第%d页出错' % page)

# 12 使用 pandas 库将 data 列表转换为 DataFrame 对象,再保存为excel文件
import pandas as pd
df = pd.DataFrame(data,columns=["id","question","answer"])
df.to_excel("39问医生.xlsx",index=False)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值