【2023最新】Python 百度贴吧 爬取文本作者以及图片

文章目录

  • 前言
  • 1 分析百度贴吧
  • 2 请求url获取源代码
  • 3 解析源代码 获取数据
  • 4 保存到csv文件
  • 5 完整源代码
  • 5 效果展示

前言

今天爬取百度贴吧

先看效果

可以输入爬取贴吧名,爬取的总页数,爬取的字段有帖子id,标题,内容,发表作者,发表时间,最后回帖人,最后回帖时间,图片

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第1张图片

爬取的时候看到中间有几个url请求了0条评论,我们看下

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第2张图片

不是反爬的问题,是网站没有

我们再看看爬取的图片

可以看到,图片也是大图没有问题

教程开始

1 分析百度贴吧

首先搜索贴吧

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第3张图片

可以看到url后面多了几个参数,我们翻到第二页继续观察

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第4张图片

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第5张图片

可以看到,百度贴吧的参数就是 kw 为搜索的关键词 ie为编码 pn为页码 一页为50

分析好url后我们就开始看他是静态资源还是动态资源

右键查看页面源代码

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第6张图片

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第7张图片

在源代码中搜索页面的内容,很明显,这个是静态资源

我们就不需要抓包了,只需要请求url就行

2 请求url获取源代码

右键检查,或者F12,打开开发者工具

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第8张图片

查看请求的url,可以看到星空那俩字被编码了,所以我们请求的时候也要编码

复制请求标头下的"User-Agent"

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第9张图片

首先尝试请求头只有一个 “User-Agent” 能不能请求成功

可以看到,请求头只放一个 UA也可以请求成功

所以我们使用UA库来防止被反爬

关于UA库点击查看 2023最新!!!Python爬虫获取 UA 工具 让你爬虫时如鱼得水的工具和模块

import random
import urllib.parse
import requests
from fake_useragent import UserAgent

# 获取网页源代码
def get_HTML(url):
    headers = {
        "User-Agent": random.choice(ua_list),
    }
    response = requests.get(url, headers=headers)
    print('请求url', url, response)
    return response.text


if __name__ == '__main__':
    # 初始化 UA 库 防止反爬
    ua = UserAgent()
    ua_list = []
    for i in range(20):
        ua_list.append(ua.random)
        
    kw = input('输入要爬取的贴吧:')
    pn = int(input('输入要爬取的总页数:'))
    for i in range(pn):
        url = f'https://tieba.baidu.com/f?kw={urllib.parse.quote(kw)}&ie=utf-8&pn={i * 50}'
        # 获取源代码
        text = get_HTML(url)

        print(text)

获取到源码后进行解析就行,我这里使用的是正则表达式

3 解析源代码 获取数据

【2023最新】Python 百度贴吧 爬取文本作者以及图片_第10张图片

我们通过源代码可以看出,每一条数据,都在一个div里面

第一步,通过re获取全部的评论div

# 存放div
lis = re.findall('(
.*?)
  • , len(lis)) # lis 49
  • 【2023最新】Python 百度贴吧 爬取文本作者以及图片_第11张图片

    再仔细看源码,可以看到他们都是有规律的,直接使用正则获取

    在我们爬取出来打印到控制台时,我们还可以看到,标题和正文,他们含有\n\r,其他字符和一些网页代码之类的

    所以我们先写一个清洗内容的函数,把\n\r之类的全部删除

    # 清洗数据,\n\r\t,   以及标签 去掉
    def text_clean(content):
        clean_new = re.sub('acla=".*?"data-flag=".*?"data-ame=".*?"', '', re.sub('[\s \<.*?\>]', '', str(content)))
        return clean_new
    

    接着在使用re正则表达式提取里面数据

    
    # 存放字典的列表
    lis_item = []
        # 循环每一条评论
        for item in lis:
            # 创建字典
            lis_dic = {}
            
            # 获取贴纸id
            num = re.findall('title="回复">(.*?)', item)[0]
            lis_dic['num'] = num  # 放入字典
            
            # 获取标题
            text_content_h1 = re.findall('(.*?)',item)
            # 判断标题是否存在
            if len(text_content_h1) > 0:
                # 存在的话放入字典并清洗内容
                lis_dic['text_content_h1'] = text_clean(text_content_h1[0])
            else:
                # 不存在为空
                lis_dic['text_content_h1'] = ''
     		
            # 获取正文文本
            text_content_h2 = re.findall('
    (.*?)
    '
    , item, re.S) # 判断是否存在 if len(text_content_h2) > 0: # 存在的话放入字典并清洗内容 lis_dic['text_content_h2'] = text_clean(text_content_h2[0]) else: # 不存在为空 lis_dic['text_content_h2'] = '' try: # 获取创建时间 time_go = re.findall('(.*?)', item)[0] except: time_go = '未知' lis_dic['time_go'] = time_go # 获取主题作者 content_author = re.findall('title="主题作者:(.*?)"', item, re.S) if len(content_author) > 0: lis_dic['content_author'] = text_clean(content_author[0]) else: lis_dic['content_author'] = '未知' # 获取最后回复人 last_author = re.findall('title="最后回复人:(.*?)">', item, re.S) if len(last_author) > 0: lis_dic['last_author'] = text_clean(last_author[0]) else: lis_dic['last_author'] = '未知' # 获取最后回复时间 last_time = re.findall('title="最后回复时间">(.*?)', item, re.S) if len(last_time) > 0: lis_dic['last_time'] = text_clean(last_time[0]) else: lis_dic['last_time'] = '未知' # 获取所有的img 注意,大图是bpic的地址 img_list = re.findall('', item, re.S) lis_dic['img_list'] = img_list # 打印字典 print(lis_dic) # 添加到列表 lis_item.append(lis_dic)

    获取数据没有问题后,把他写成函数,传入参数为html源代码

    # 获取html,解析数据
    def get_data(text):
        # 存放div
        lis = re.findall('(
    .*?)
  • , len(lis)) # lis 49 # 存放字典的列表 lis_item = [] # 循环每一条评论 for item in lis: # 创建字典 lis_dic = {} # 获取贴纸id num = re.findall('title="回复">(.*?)', item)[0] lis_dic['num'] = num # 放入字典 # 获取标题 text_content_h1 = re.findall('(.*?)', item) # 判断标题是否存在 if len(text_content_h1) > 0: # 存在的话放入字典并清洗内容 lis_dic['text_content_h1'] = text_clean(text_content_h1[0]) else: # 不存在为空 lis_dic['text_content_h1'] = '' # 获取正文文本 text_content_h2 = re.findall('
    (.*?)
    '
    , item, re.S) # 判断是否存在 if len(text_content_h2) > 0: # 存在的话放入字典并清洗内容 lis_dic['text_content_h2'] = text_clean(text_content_h2[0]) else: # 不存在为空 lis_dic['text_content_h2'] = '' try: # 获取创建时间 time_go = re.findall('(.*?)', item)[0] except: time_go = '未知' lis_dic['time_go'] = time_go # 获取主题作者 content_author = re.findall('title="主题作者:(.*?)"', item, re.S) if len(content_author) > 0: lis_dic['content_author'] = text_clean(content_author[0]) else: lis_dic['content_author'] = '未知' # 获取最后回复人 last_author = re.findall('title="最后回复人:(.*?)">', item, re.S) if len(last_author) > 0: lis_dic['last_author'] = text_clean(last_author[0]) else: lis_dic['last_author'] = '未知' # 获取最后回复时间 last_time = re.findall('title="最后回复时间">(.*?)', item, re.S) if len(last_time) > 0: lis_dic['last_time'] = text_clean(last_time[0]) else: lis_dic['last_time'] = '未知' # 获取所有的img 注意,大图是bpic的地址 img_list = re.findall('', item, re.S) lis_dic['img_list'] = img_list # 打印字典 print(lis_dic) # 添加到列表 lis_item.append(lis_dic) print('lis_item数量',len(lis_item)) return lis_item
  • 4 保存到csv文件

    # csv标头
    headers = ('num', 'text_content_h1', 'text_content_h2', 'time_go', 'content_author', 'last_author', 'last_time','img_list')
    
    with open(f'百度贴吧__{kw}.csv', mode='w+', encoding='utf-8', newline="")as f:
        # 创建一个字典数据的写入对象
        writer = csv.DictWriter(f, fieldnames=headers)
        writer.writeheader()  # 写入表头
        # 写数据
        writer.writerows(all_list_data) # all_list_data是列表,列表里面是字典,字典是每一条评论的内容
        print(f'百度贴吧__{kw}.csv保存成功')
    

    【2023最新】Python 百度贴吧 爬取文本作者以及图片_第12张图片

    5 完整源代码

    import csv
    import random
    import re
    import urllib.parse
    import requests
    from fake_useragent import UserAgent
    
    # 获取网页源代码
    def get_HTML(url):
        headers = {
            "User-Agent": random.choice(ua_list),
        }
        response = requests.get(url, headers=headers)
        print('请求url', url, response)
        return response.text
    
    # 清洗数据,\n\r\t,   以及标签 去掉
    def text_clean(content):
        clean_new = re.sub('acla=".*?"data-flag=".*?"data-ame=".*?"', '', re.sub('[\s \<.*?\>]', '', str(content)))
        return clean_new
    
    # 获取html,解析数据
    def get_data(text):
        # 存放div
        lis = re.findall('(
    .*?)
  • , len(lis)) # lis 49 # 存放字典的列表 lis_item = [] # 循环每一条评论 for item in lis: # 创建字典 lis_dic = {} # 获取贴纸id num = re.findall('title="回复">(.*?)', item)[0] lis_dic['num'] = num # 放入字典 # 获取标题 text_content_h1 = re.findall('(.*?)', item) # 判断标题是否存在 if len(text_content_h1) > 0: # 存在的话放入字典并清洗内容 lis_dic['text_content_h1'] = text_clean(text_content_h1[0]) else: # 不存在为空 lis_dic['text_content_h1'] = '' # 获取正文文本 text_content_h2 = re.findall('
    (.*?)
    '
    , item, re.S) # 判断是否存在 if len(text_content_h2) > 0: # 存在的话放入字典并清洗内容 lis_dic['text_content_h2'] = text_clean(text_content_h2[0]) else: # 不存在为空 lis_dic['text_content_h2'] = '' try: # 获取创建时间 time_go = re.findall('(.*?)', item)[0] except: time_go = '未知' lis_dic['time_go'] = time_go # 获取主题作者 content_author = re.findall('title="主题作者:(.*?)"', item, re.S) if len(content_author) > 0: lis_dic['content_author'] = text_clean(content_author[0]) else: lis_dic['content_author'] = '未知' # 获取最后回复人 last_author = re.findall('title="最后回复人:(.*?)">', item, re.S) if len(last_author) > 0: lis_dic['last_author'] = text_clean(last_author[0]) else: lis_dic['last_author'] = '未知' # 获取最后回复时间 last_time = re.findall('title="最后回复时间">(.*?)', item, re.S) if len(last_time) > 0: lis_dic['last_time'] = text_clean(last_time[0]) else: lis_dic['last_time'] = '未知' # 获取所有的img 注意,大图是bpic的地址 img_list = re.findall('', item, re.S) lis_dic['img_list'] = img_list # 打印字典 print(lis_dic) # 添加到列表 lis_item.append(lis_dic) print('lis_item数量',len(lis_item)) return lis_item if __name__ == '__main__': # 初始化 UA 库 防止反爬 ua = UserAgent() ua_list = [] for i in range(20): ua_list.append(ua.random) kw = input('输入要爬取的贴吧:') pn = int(input('输入要爬取的总页数:')) all_list_data = [] for i in range(pn): url = f'https://tieba.baidu.com/f?kw={urllib.parse.quote(kw)}&ie=utf-8&pn={i * 50}' # 获取源代码 text = get_HTML(url) it_list = get_data(text) all_list_data += it_list print('all_list_data', len(all_list_data)) # 写入csv headers = ('num', 'text_content_h1', 'text_content_h2', 'time_go', 'content_author', 'last_author', 'last_time', 'img_list') # 元组 列表 集合 with open(f'百度贴吧__{kw}.csv', mode='w+', encoding='utf-8', newline="")as f: # 创建一个字典数据的写入对象 writer = csv.DictWriter(f, fieldnames=headers) writer.writeheader() # 写入表头 # 写数据 writer.writerows(all_list_data) print(f'百度贴吧__{kw}.csv保存成功')
  • 5 效果展示

    爬取20页并保存到csv文件

    【2023最新】Python 百度贴吧 爬取文本作者以及图片_第13张图片

    你可能感兴趣的:(爬虫,python,百度,dubbo)