json的用法
储存为json文件出现unicode编码
filename = 'Bili.json'
with open(filename, 'w', encoding='utf-8') as file_obj:
json.dump(Bili, file_obj, ensure_ascii=False)
一定要加ensure_ascii=False,这个可以解决json文件里面unicode编码问题。
储存进去之后读文件,时时刻刻记得encoding=utf-8
filename='Bili.json'
with open(filename, "r", encoding="utf-8") as file_obj:
json.load(file_obj, encoding = "utf-8")
print(Bili)
动态爬取
这个是爬取bilibili 后浪 下面的评论+评论者+评论排名
一个好神奇的方法,也不知道原理是啥。
import requests
import json
headers = { }
res = requests.get('https://api.bilibili.com/x/v2/reply?pn=1&type=1&oid=412935552&sort=2', headers=headers)
# https://api.bilibili.com/x/v2/reply?callback=jQuery172007300442430029852_1605323367404&jsonp=jsonp&pn=1&type=1&oid=412935552&sort=2&_=1605323368081
js = json.loads(res.text)
lis = []
for i in js['data']['replies']:
x = {}
x['text'] = i['content']['message']
x['author'] = i['member']['uname']
x['level'] = i['member']['level_info']['current_level']
lis.append(x)
print(lis)
1.F12打开这里,然后network中找到reply开头的那一行,点进去headers先获取Request URL,然后删掉一些不需要的内容(见上面代码)
2.点击preview,会发现data下面的replies里有这一页全部的评论、评论者、排名什么的,用一个for循环遍历这里面的东西。
代码就是:
for i in js['data']['replies']:
3.然后开始愉快获取内容(看图片就能懂)
代码是:
x = {}
x['text'] = i['content']['message']
x['author'] = i['member']['uname']
x['level'] = i['member']['level_info']['current_level']
爬标题和排行
主要学习css选择器定位的方法
for r in range(1, 101):
x = {}
x['name'] = soup.select('.rank-list li:nth-of-type(' + str(r) + ') .info > a')[0].text
# select必须返回列表,要加一个[0]
x['rank'] = soup.select('.rank-list li:nth-of-type(' + str(r) + ') >.num')[0].text
Bili.append(x)
这里name中的意思是,找类名为 rank-list 下的第1、2、3……个 li 标签 ,再找这些 li 标签里面类名为info下的子标签a中的文本。rank基本同理。
(' + str(r) + ')
这个是字符串拼接,因为r从1到100,就是上面说的找类名为 rank-list 下的第1、2、3……个 li 标签。
其他用法:字符串拼接.
大佬师兄爬标题up主播放量弹幕
import requests
from bs4 import BeautifulSoup
import json
url = 'https://www.bilibili.com/v/popular/rank/all'
r = requests.get(url)
# r.text源代码, soup将源代码转化成BeautifulSoup的对象
soup = BeautifulSoup(r.text, 'lxml')
bilibili = []
divs_content = soup.select('div.content')
for divs_content in divs_content:
div_info = divs_content.select_one('div.info')
title = div_info.select_one('a.title').text.strip()
# 标签对象是可以嵌套查询的(嵌套select)
div_detail = div_info.select_one('div.detail')
data_boxes = div_detail.select('span.data-box')
play_number = data_boxes[0].text.strip()
danmu_number = data_boxes[1].text.strip()
author = data_boxes[2].text.strip()
bilibili.append([title, play_number, danmu_number, author])
'''储存为txt文本'''
with open("./bili_top100.txt", "w", encoding="utf-8") as f:
for bili in bilibili:
result = "".join([str(e) for e in bili])
f.write(result+"\n")
'''储存为json文件'''
filename = 'Bili_top100.json'
with open(filename, 'w', encoding='utf-8') as file_obj:
json.dump(bilibili, file_obj, ensure_ascii=False)
strip()方法
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
11/14用另外一种方法爬标题播放量
import requests
from bs4 import BeautifulSoup
import json
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
}
res = requests.get('https://www.bilibili.com/v/popular/rank/all',headers=header)
html = BeautifulSoup(res.text)
lis = []
for i in html.select('.rank-list li'):
x = {}
x['name'] = i.select('.info > a')[0].text
x['rank'] = i.select('.num')[0].text
x['view'] = i.select('.detail > .data-box')[0].text.strip()
lis.append(x)
# print(lis)
with open('1.json','w+',encoding='utf-8') as file:
js = json.dumps(lis, ensure_ascii=False)
file.write(js)
零碎内容
# 只知道标签名
# result = soup.select_one("a")
# print(result)
# select_one:返回一个结果(返回值是list的首个)
# select:返回全部结果
# 返回查找到的元素的第一个标签
# 例:选择class类名为sister的所有标签中的第一个。
# print(soup.select_one('.sister'))
# 找规律:div标签中的a标签,div有一个属性class=info, .代表class,#代表id
# result = soup.select_one("div[class=info]div a")
# 上面的即result = html.select_one("div.info a")
# 遇到多个class的情况:用.将全部class链接起来
# result = soup.select_one(".w-later.van-watchlater a")
# 已经得到标签对象了result
# print(result)
# 我要拿标签中的文本
# print(result.text)
# 我要的是标签的属性(attrs是一个字典)
# print(result.attrs)
文件夹还有个PPT 11.13爬虫基础,有啥不懂的记得看。