【Python 爬虫入门项目】获取某站热门前100相关内容存到csv中

目录

1.爬虫介绍

2.1任务1:找到返回后台数据的URL

2.2 任务2:根据URL获取其中一页json数据并通过vscode规整代码

2.3  任务3:通过python爬取这个5个json文本(每个页面20条记录,共100条)

(1) 导入所需库

(2) 设置请求头——假装浏览器反反扒的第一步 

(3) 爬下第一页的20条热门数据json文本 

(4) 分析所需数据位置

(5) 循环获取5页共100条热门数据 ——f字符串语句

2.4  任务4:存到本地csv表【2】

 3.完整代码

4.后话

5.参考致谢


爬虫文章不能出现被获取(spider)网站页面,审核的哥哥姐姐辛苦了!

1.爬虫介绍

        一句话,假装浏览器向服务器发送请求获取大量数据,常见有get请求(直接回获取数据),post请求(发送表单来获取类似于注册登录等)

2.1任务1:找到返回后台数据的URL

下图为某站热门页面

某站主页->热门->综合热门 ,进入一条条的热门视频推荐页面

也就是在这个网址

  或者

进入热门页面之后:

 操作:F12 -> network -> XHR -> F5(一定要F5刷新一下) 【3】

        首先,根据经验,热门视频列表是一直可以往下拉更新的,因此在html里面找到所有数据是不可能的,肯定是通过一个URL请求后台数据,每下拉到底自动从后台请求下一页数据再传到html最后渲染出来。

        要找到请求后台数据这个URL可以往下多刷几页,就会看见规律,因此我们知道该页面是通过这个XHR类型的popular?ps={一次20个数据项}&pn{第几页}里面的url请求数据的。

   参照下图Request URL

(注意我们编程时通过改变pn=数字来获取不同页数据)

同时我们也能通过请求方法method为GET验证本页面通过get请求服务器数据并返回

2.2 任务2:根据URL获取其中一页json数据并通过vscode规整代码

小小实践一下访问这个第一页pn=1的URL看得到什么 

当 pn = 1

如果无法打开那就自己输入这个pn=1的url到搜索引擎去打开吧,可能这个连接是从csdn跳转出去的某站不给你访问。

         这不正是我们要找的吗?看不清楚可以将这个网页所有内容复制粘贴到vscode文本,shift+alt+f 格式规整后,可以看出就是一个这个网页上是json文件(JSON 就是 Javascript 对象和数组的字符串表示法,它使用文本表示一个 JS 对象或数组的信息,因此,JSON 的本质是字符串【1】)的形式(后续python爬取出来的text是str类型,还得通过json库将str转换成字典数据类型),后续可以通过python的字典与列表处理

2.3  任务3:通过python爬取这个5个json文本(每个页面20条记录,共100条)

(1) 导入所需库

import requests # 相当于浏览器发起请求
import json # 内置的库,不用下载 ,处理json数据的转换等操作
import csv #内置,处理csv文件按存取等操作

(2) 设置请求头——假装浏览器反反扒的第一步 

 找到这个请求头,里面的User-Agent是伪装最重要的,一般有了这个可以解决大部分反扒。

        

         我们声明一个headers字典,将User-Agent及其值复制到里面。有的项目还用到Cookie

# 用自己的就可以了
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3"
}

(3) 爬下第一页的20条热门数据json文本 

i = 1 # i为for循环做准备    
URL = f"https://api.bilibili.com/x/web-interface/popular?ps=20&pn={i}"
response = requests.get(URL,headers = headers)
# print(response.text) # response.text为str型的页面数据 
dict_heat = json.loads(response.text) # 将str转换成json格式数据
print(dict_heat)

有内容打印就行,内容会随着热门的改变而不一样 。

规整代码后清晰明了

(4) 分析所需数据位置

关键!关键!关键!这里字典与列表、字典与字典疯狂套套套 

(抱歉,下图是要找title不是tname,即最外层字典名["data"]["list"][0]["title"],懒得改图了)

        再举一个例子,要得到第2个(则列表下标为1)热门tname,最外层字典名为dict_heat,则dict_heat["data"]["list"][1]["tname]

(5) 循环获取5页共100条热门数据 ——f字符串语句

# ps = 20 ,100 = 1*5
'''
我们需要类型tname,标题名title、描述desc,up主name、观看量view、弹幕数danmaku、点赞like,收藏favorite,硬币数coin
我们用字典dict_coint的键值对形式存储一条热门的上面这几个数据,因此,将这几个数据提取出来存进字典
我们用列表list_top100存储每一条热门字典
'''
list_top100 = []
# i从1-5,分别对应五个URL,每次循环就相当于浏览器每下拉到底就更新一页的20条热门
for i in range(1,6):
    URL = f"https://api.bilibili.com/x/web-interface/popular?ps=20&pn={i}"
    response = requests.get(URL,headers = headers)
    #print(type(response.text))
    dict_heat = json.loads(response.text)
    # print(dict_heat) 
    # 处理字典获取类型tname,标题名title、描述desc,up主name、观看量view、弹幕数danmaku、点赞like,收藏favorite,硬币数coin
    # li从0-19,每一个dict_heat字典list有20个热门,每次循环就是每条热门
    for li in range(20):
        dict_coint = {"tname":"","title":"","desc":"","owner":"","view":"","danmaku":"","like":"","favorite":"","coin":""}
        dict_coint["tname"] = dict_heat["data"]["list"][li]["tname"]
        dict_coint["title"] = dict_heat["data"]["list"][li]["title"]
        dict_coint["desc"] = dict_heat["data"]["list"][li]["desc"]
        dict_coint["owner"] = dict_heat["data"]["list"][li]["owner"]["name"]
        dict_coint["view"] = dict_heat["data"]["list"][li]["stat"]["view"]
        dict_coint["danmaku"] = dict_heat["data"]["list"][li]["stat"]["danmaku"]
        dict_coint["like"] = dict_heat["data"]["list"][li]["stat"]["like"]
        dict_coint["favorite"] = dict_heat["data"]["list"][li]["stat"]["favorite"]
        dict_coint["coin"] = dict_heat["data"]["list"][li]["stat"]["coin"]
        list_top100.append(dict_coint)
print(list_top100)

2.4  任务4:存到本地csv表【2】

with open(r"bilibili_top100.csv","w",encoding='utf-8-sig',newline='' ) as f:
    csv_writer = csv.writer((f))
    # 先写一行表头,我为了美观多加了一行序号
    csv_writer.writerow(["序号","类型","标题","描述","up主","浏览量","弹幕数","点赞数","收藏数","投币数"])
    # 还是注意多了序号
    # dodo是每次列表list_top100返回的一个字典
    for i, doto in enumerate(list_top100):
         csv_writer.writerow([i+1,doto["tname"],doto["title"],doto["desc"],doto["owner"],doto["view"],doto["danmaku"],doto["like"],doto["favorite"],doto["coin"]])

文件路径因为我是就在同级文件夹里

 3.完整代码

import requests # 相当于浏览器发起请求
from bs4 import BeautifulSoup #本次没用到
import json # 内置的库,不用下载 ,处理json数据的转换等操作
import csv #内置,处理csv文件按存取等操作

# 请求该网址获取热门数据json
url = "https://api.bilibili.com/x/web-interface/popular?ps=20&pn="
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3",
    #"Cookie":"buvid3=A2DE5D15-AB31-3498-3CBC-FAA2758718BC90917infoc; b_nut=1668129090; i-wanna-go-back=-1; _uuid=EE5768D2-C2C4-10AFE-102101-2108FF6310FB6791645infoc; nostalgia_conf=-1; LIVE_BUVID=AUTO2516681291427415; fingerprint=275df7b8b6dd68ec39d06535391183fd; buvid_fp_plain=undefined; PVID=1; b_ut=5; rpdid=0zbfAGvvia|1n8AfspM|1Ej|3w1OYp9G; CURRENT_BLACKGAP=0; is-2022-channel=1; CURRENT_FNVAL=4048; CURRENT_QUALITY=80; buvid_fp=275df7b8b6dd68ec39d06535391183fd; header_theme_version=CLOSE; CURRENT_PID=92db9e00-d55b-11ed-918b-ef0265900a07; FEED_LIVE_VERSION=V8; buvid4=DD914872-814A-E541-6411-AECE343B81A592381-022111109-QvnVcBMEUB9cj5ReWWq3ZPeCDe2iT%2F3aV%2FgOVu0WxxdlybTyg0qT7g%3D%3D; innersign=0; b_lsid=B53AC6D2_1881CE410C6; bsource=search_bing; home_feed_column=4; browser_resolution=1396-685; bp_video_offset_397001083=795738040063492200; SESSDATA=fc5e1f63%2C1699666280%2C63116%2A51; bili_jct=8b97f5de15f0e146666e1043c9311286; DedeUserID=397001083; DedeUserID__ckMd5=6986d46441593e09; sid=ftstla3y"
    #"Cookie":"buvid3=A2DE5D15-AB31-3498-3CBC-FAA2758718BC90917infoc; b_nut=1668129090; i-wanna-go-back=-1; _uuid=EE5768D2-C2C4-10AFE-102101-2108FF6310FB6791645infoc; nostalgia_conf=-1; LIVE_BUVID=AUTO2516681291427415; fingerprint=275df7b8b6dd68ec39d06535391183fd; buvid_fp_plain=undefined; PVID=1; b_ut=5; rpdid=0zbfAGvvia|1n8AfspM|1Ej|3w1OYp9G; CURRENT_BLACKGAP=0; is-2022-channel=1; CURRENT_FNVAL=4048; CURRENT_QUALITY=80; buvid_fp=275df7b8b6dd68ec39d06535391183fd; header_theme_version=CLOSE; CURRENT_PID=92db9e00-d55b-11ed-918b-ef0265900a07; FEED_LIVE_VERSION=V8; buvid4=DD914872-814A-E541-6411-AECE343B81A592381-022111109-QvnVcBMEUB9cj5ReWWq3ZPeCDe2iT%2F3aV%2FgOVu0WxxdlybTyg0qT7g%3D%3D; innersign=0; b_lsid=B53AC6D2_1881CE410C6; bsource=search_bing; home_feed_column=4; browser_resolution=1396-685; bp_video_offset_397001083=795738040063492200; sid=fnz9238s"
}
# ps = 20 ,100 = 1*5
list_top100 = []
for i in range(1,6):
    URL = f"https://api.bilibili.com/x/web-interface/popular?ps=20&pn={i}"
    response = requests.get(URL,headers = headers)
    #print(type(response.text)) #test code: 200
    dict_heat = json.loads(response.text)
    # print(dict_heat) Sucess
    # 处理字典获取类型tname,标题名title、描述desc,up主name、观看量view、弹幕数danmaku、点赞like,收藏favorite,硬币数coin
    for li in range(20):
        dict_coint = {"tname":"","title":"","desc":"","owner":"","view":"","danmaku":"","like":"","favorite":"","coin":""}
        dict_coint["tname"] = dict_heat["data"]["list"][li]["tname"]
        dict_coint["title"] = dict_heat["data"]["list"][li]["title"]
        dict_coint["desc"] = dict_heat["data"]["list"][li]["desc"]
        dict_coint["owner"] = dict_heat["data"]["list"][li]["owner"]["name"]
        dict_coint["view"] = dict_heat["data"]["list"][li]["stat"]["view"]
        dict_coint["danmaku"] = dict_heat["data"]["list"][li]["stat"]["danmaku"]
        dict_coint["like"] = dict_heat["data"]["list"][li]["stat"]["like"]
        dict_coint["favorite"] = dict_heat["data"]["list"][li]["stat"]["favorite"]
        dict_coint["coin"] = dict_heat["data"]["list"][li]["stat"]["coin"]
        list_top100.append(dict_coint)
print(list_top100)
with open(r"bilibili_top100.csv","w",encoding='utf-8-sig',newline='' ) as f:
    csv_writer = csv.writer((f))
    csv_writer.writerow(["序号","类型","标题","描述","up主","浏览量","弹幕数","点赞数","收藏数","投币数"])
    for i, doto in enumerate(list_top100):
         csv_writer.writerow([i+1,doto["tname"],doto["title"],doto["desc"],doto["owner"],doto["view"],doto["danmaku"],doto["like"],doto["favorite"],doto["coin"]])

4.后话

通过获取json,我们还能看到封面url、视频连接等其他数据, 

5.参考致谢

 【1】csdn——JSON 本质就是字符串???( 刚学JSON时)

 【2】来自博客园——解决写入csv读取乱码——utf-8-sig

 【3】csdn——有关XHR是什么

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值