时间:2024-02-10 16:45:01 | 来源:网站运营
时间:2024-02-10 16:45:01 来源:网站运营
Python如何爬动态网页,详细教程,小菜鸟一个?:在之前的推文中,我们介绍了如何爬取一个简单的静态网站——「Python 爬取静态网站:以历史天气为例」,但是在实际过程中,常常会遇到需要爬取动态网站数据的情况。在本文中,我们也将通过一个比较简单的案例,来介绍爬取动态网站数据的基本思路和步骤。
bilibili
视频评论为例,来具体介绍如何通过 Python 爬取动态网页的数据。主要内容包括:json
格式数据; 如何把数据实时存入 csv
文件; 如何循环爬取多页数据。# 导入模块import requestsimport time# 网址url = "https://api.bilibili.com/x/v2/reply/main" # 接口网址的主要结构# 请求头数据headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://www.bilibili.com/video/BV16X4y1g7wT', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': 'Windows', 'sec-fetch-dest': 'script', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36' # 根据测试不需要 cookie 信息也可以获取数据 # 需要 cookie 的话在自己的浏览器中复制,这里涉及隐私就不放 cookie 信息了}# 构造请求参数params = { # 'callback': 'jQuery17201888299578386794_' + str(round(time.time() * 1000)), # 'jsonp': 'jsonp', 'next': 0, # 页码 'type': 1, 'oid': 715024588, # 视频av号 # 'mode': 3, # 评论排序方式 # 'plat': 1, # '_': str(round(time.time() * 1000)) # 生成当前时间戳}# 通过get方法请求数据response = requests.get(url, headers=headers, params=params)
查看返回结果,<Response [200]> 代表请求数据成功。如果是 403 或 404 则说明请求不成功,可能需要检查电脑网络是否通畅、目标网址是否可以正常访问、headers
是否有正确设置等。json
格式存储的,而每条评论的数据在 data
下面的replies
中。# 导入模块import jsonimport timeresponse.encoding = 'utf-8' # 修改编码格式data_json = json.loads(response.text) # 通过 json 解析数据comment_list = data_json['data']['replies'] # 获取 data 下面的 replies 列表comments = [] # 构建空列表保存每页的评论数据for i in range(len(comment_list)): # 循环获取每条评论的数据 comment = { 'id': comment_list[i]['rpid'], # 评论id # 评论时间,由时间戳转换 'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(comment_list[i]['ctime'])), 'parent': comment_list[i]['parent'], # 父评论id 'like': comment_list[i]['like'], # 点赞数 'user_id': comment_list[i]['member']['mid'], # 评论用户id 'user_name': comment_list[i]['member']['uname'], # 用户名 'content': comment_list[i]['content']['message'] # 评论内容 # 需要其他数据的可以再在 json 中查看并获取对应的名称 } comments.append(comment) # 每页的评论数据
# 导入模块import csv# 保存数据的文件路径save_path = 'bilibili.csv'# 将数据写入 csv with open(save_path, 'a', newline='', encoding='utf-8') as fp: csv_header = ['id', 'time', 'parent', 'like', 'user_id', 'user_name', 'content'] # 设置表头,即列名 csv_writer = csv.DictWriter(fp, csv_header) # 如果文件不存在,则写入表头;如果文件已经存在,则直接追加数据不再次写入表头 if fp.tell() == 0: csv_writer.writeheader() csv_writer.writerows(comments) # 写入数据
# -*- coding: utf-8 -*-# Author: W.Y.# Email: wangyingchn@outlook.com# Date: 2022/4/12# 导入模块import requests # 请求数据import time # 时间模块import json # json 模块,储存数据import csv # 保存数据# 请求数据def get_response(page): url = 'https://api.bilibili.com/x/v2/reply/main' # 接口网址的主要结构 # 请求头数据 headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://www.bilibili.com/video/BV16X4y1g7wT', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': 'Windows', 'sec-fetch-dest': 'script', 'sec-fetch-mode': 'no-cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36' # 根据测试不需要 cookie 信息也可以获取数据 # 需要 cookie 的话在自己的浏览器中复制,这里涉及隐私就不放 cookie 信息了 } # 构造请求参数 params = { # 'callback': 'jQuery17201888299578386794_' + str(round(time.time() * 1000)), # 'jsonp': 'jsonp', 'next': page, # 页码 'type': 1, 'oid': 715024588, # 视频av号 'mode': 3, # 评论排序方式 # 'plat': 1, # '_': str(round(time.time() * 1000)) # 生成当前时间戳 } # 通过get方法请求数据 response = requests.get(url, headers=headers, params=params) return response# 解析数据def parse_data(response): response.encoding = 'utf-8' # 修改编码格式 data_json = json.loads(response.text) # 通过 json 解析数据 comment_list = data_json['data']['replies'] # 获取 data 下面的 replies 列表 comments = [] # 构建空列表保存每页的评论数据 for i in range(len(comment_list)): # 循环获取每条评论的数据 comment = { 'id': comment_list[i]['rpid'], # 评论id 'time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(comment_list[i]['ctime'])), # 评论时间,由时间戳转换 'parent': comment_list[i]['parent'], # 父评论id 'like': comment_list[i]['like'], # 点赞数 'user_id': comment_list[i]['member']['mid'], # 评论用户id 'user_name': comment_list[i]['member']['uname'], # 用户名 'content': comment_list[i]['content']['message'] # 评论内容 # 需要其他数据的可以再在 json 中查看并获取对应的名称 } comments.append(comment) # 每页的评论数据 return comments# 保存数据def save_data(comments, save_path): with open(save_path, 'a', newline='', encoding='utf-8') as fp: # 设置表头,即列名 csv_header = ['id', 'time', 'parent', 'like', 'user_id', 'user_name', 'content'] csv_writer = csv.DictWriter(fp, csv_header) # 如果文件不存在,则写入表头;如果文件已经存在,则直接追加数据不再次写入表头 if fp.tell() == 0: csv_writer.writeheader() csv_writer.writerows(comments) # 写入数据# 定义爬取函数def crawler(page, save_path): time.sleep(2) # 暂停 2 秒,避免请求过于频繁 response = get_response(page) # 请求数据 comments = parse_data(response) # 解析数据 save_data(comments, save_path) # 储存数据 print(f'成功爬取第{page+1}页')if __name__ == '__main__': save_file = 'bilibili.csv' # 保存路径 total_counts = 1000 # 爬取 1000 条评论 # 如果要爬取所有评论,可以改成全部评论数。 # 如果要爬取多个视频的评论,可以通过下面的代码,爬取第一页的时候返回所有的评论数 # total_counts = data_json['data']['cursor']['all_count'] # 页码循环,每页有 20 条评论,所以通过总评论数计算页码 for p in range(total_counts//20 + 1): crawler(p, save_file)
详细内容参见连享会推文Note:产生如下推文列表的 Stata 命令为:. lianxh Python
. songbl Python
安装最新版lianxh
/songbl
命令:. ssc install lianxh, replace
. ssc install songbl, replace
关键词:教程,详细,动态,小菜