【BeautifulSoup】、【使用BeautifulSoup抓取QZZN论坛中每个帖子的标题、url及对应帖子的回复内容】

一、数据解析常用的三种方式——③BeautifulSoup
1.使用时需要使用BS转类型

response = requests.get(url,headers=self.headers)
#转类型-------------<class 'bs4.BeautifulSoup'>
#默认bs4会调用你系统中的lxml的解析库 警告提示
#如果不想看到警告,可以主动设置  bs4的解析库----features="lxml"
soup = BeautifulSoup(data,'lxml')

2.通用解析方法
①find----返回符合查询条件的第一个标签

result = soup.find(name='p')
result = soup.find(attrs={'class':'title'})

②find_all-----传标签(a)或者传属性(attrs={’’:’’})

result = soup.find_all('a')
result = soup.find_all('a',limit=1)#其实就是.find()的源码,只取第一个
result = soup.find_all(attrs={"class":"sister"})

③select_one-----传css的选择器(前端的内容)—只取第一个

result = soup.select_one('.sister')#类选择器

④select-----传css选择器,取得是集合-----返回list

result = soup.select('.sister')#类选择器
result = soup.select('#link1')#id选择器
result = soup.select('a[id="link2"]')
result = soup.select('title,.title')
result = soup.select('head title')

⑤select-----传css选择器-----取标签包裹得内容
注:.get_text()是获取文字

result = soup.select('b')[0].get_text()#.get_text()是获取文字

⑥select-----传css选择器-----取标签的属性
注:.get(‘href’)是获取属性

result = soup.select('#link1')[0].get('href')#.get('href')是获取属性

3.通用解析方法的完整测试代码

#pip install beautifulsoup

from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" id="link2><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""
#1.转类型-------------<class 'bs4.BeautifulSoup'>
soup = BeautifulSoup(html_doc,'lxml')
#2.通用解析方法

#①find----返回符合查询条件的第一个标签
result = soup.find(name='p')
result = soup.find(attrs={'class':'title'})
#②find_all-----传标签(a)或者传属性(attrs={'':''})
result = soup.find_all('a')
result = soup.find_all('a',limit=1)#其实就是.find()的源码,只取第一个
result = soup.find_all(attrs={"class":"sister"})
#③select_one-----传css的选择器(前端的内容)
result = soup.select_one('.sister')#类选择器
#④select-----传css选择器,取得是集合-----返回list
result = soup.select('.sister')#类选择器
result = soup.select('#link1')#id选择器
result = soup.select('a[id="link2"]')
result = soup.select('title,.title')
result = soup.select('head title')
#取标签包裹得内容----返回的是list
result = soup.select('b')[0].get_text()#.get_text()是获取文字
#取标签的属性
result = soup.select('#link1')[0].get('href')#.get('href')是获取属性
print(result)

二、代码——使用BS4抓取QZZN帖子的标题和链接,并抓取每个链接下帖子的回复内容

from bs4 import BeautifulSoup
import requests
import json
import time

class QZZNspider(object):
    def __init__(self):
        self.url = 'https://bbs.qzzn.com/forum-133-{}.html'
        self.headers =  {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1'
}
       #保存数据
        self.data_list = []#用来存储帖子的标题及链接
        self.data_detail = []#用来存储每一个帖子下面的回复内容

    #1. 发请求
    def get_response(self,url):
        response = requests.get(url,headers=self.headers)
        data = response.content#数据为二进制类型
        return data

    #2.  解析数据 list(对应一个网页中帖子的标题及链接)
    def parse_data(self,data):
        #1.转类型
        soup = BeautifulSoup(data,'lxml')
        #2.解析内容
        my_object_list = soup.find_all(attrs={'class':'s xst'})#类选择器,class="s xst
        for single_object in my_object_list:
            final_dic = {}
            final_dic['title'] = single_object.get_text()#取出标题
            final_dic['url'] = "http://bbs.qzzn.com/"+single_object.get('href')
            self.data_list.append(final_dic)#填充至self.data_list[]

    #2.解析详情页 detail(对应每一个帖子下面的回复内容)
    def parse_detail_data(self,data):
        html_data = BeautifulSoup(data,'lxml')
        #取出问题测试
        question_test = html_data.find_all(attrs={'id': 'thread_subject'})
        if question_test != []:#判断问题测试是不是空集:因为有的帖子可能要求权限大于多少(或者登录之后才能访问),因此先加判断能否正常提出标题(即能否正常访问),若能提出标题,再进行后续的回复提取!
            question = question_test[0].get_text()
        #存入问题
            detail_question_dic = {
                'Question': question
            }
            self.data_detail.append(detail_question_dic)#将问题填充至self.data_detail[]
            answer_list = html_data.select('.t_f')#取出所有的回复
            for index,answer in enumerate(answer_list):
                answer_list_final = []
                answer_list_final.append(answer.get_text().replace('\n', '').replace('\r', '').replace('\xa0',''))#把回复中无用的'\n','\r','\xao'去掉
                detail_dic = {
                'Answer'+format(index+1):answer_list_final
            }#给Answer添加一个标签,变成Answer1、Answer2......
                self.data_detail.append(detail_dic)
        else:
            print('无法访问的帖子')#无法访问的帖子,在terminal中打印提示

    #3.  保存数据
    def save_data(self,data,file_path):
        data_str = json.dumps(data)#转为字符串类型
        with open(file_path,'w')as f:
            f.write(data_str)

    #4.启动
    def start(self):
        #发送列表页请求
        for i in range(1,10):#仅是用了一个for循环就能实现翻页的功能
            url = self.url.format(i)
            data = self.get_response(url)
            self.parse_data(data)
        self.save_data(self.data_list,'qzznspider.json')#因self.data_list是在__init__(self)中定义的,因此不用在for循环里保存
        #发送详情页的请求-----相当于把之前取出的每一个title对应的url取出来,依次对每个url进行发送请求,返回的'response'进行数据解析,具体步骤与第一次取title和url相类似
        for data in self.data_list:
            detail_url = data['url']
            print(detail_url)
            detail_data = requests.get(detail_url).content
            #解析详情页的数据
            self.parse_detail_data(detail_data)
        self.save_data(self.data_detail,'detail.json')
QZZNspider().start()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值