在这个实例中用到了手机模式下的动态网页爬取,实际上手机模式下的动态网页爬取一般比PC模式下的动态网页爬取简单些(因为手机模式下基本上都是动态网站,很少有伪动态网站)。
手机模式的操作:点击切换模式仿真(切换之后基本上就是手机模式了)——>点击网页刷新(如果看着不舒服可以点击刷新下面一栏的尺寸,选择自己喜欢的机型)——>向下滑直至翻页出现新的内容,剩下的跟之前讲的操作一样:python爬虫思路——动态网站
代码里cookie什么的用自己浏览器的,不会找的看这篇文章:python爬虫思路——静态网站
话就这么多,上代码:
import re
import time
import requests
import json
#获得热搜话题的标题
#这里用的是pc端的页面的headers
def get_title(hot_band_url):
headers = {
'user_agent' : '用自己浏览器的',
'cookie':'用自己浏览器的',
}
data = requests.get(hot_band_url,headers=headers) #请求
data = json.loads(data.text) #转字典格式
title_list = []
items = data['data'] if 'data' in data else {} #找数据
items = items['band_list'] if 'band_list' in items else {} #找榜单列表
for item in items:
title = item['word'] if 'word' in item else None
#如果找到标题,存入列表
if title != None:
title_list.append(title)
return title_list
#获得所有热搜话题里的微博的id
# 这里用的是手机端的页面的headers
def get_id(title_list): #
headers = {
'user_agent': '用自己浏览器的',
'cookie': '用自己浏览器的',
}
id_list = []
num = 0
for title in title_list:
time.sleep(3) # 设置爬虫延时
# 根据获取的标题进入该内容网页存放数据的文件
url = 'https://m.weibo.cn/api/container/getIndex?containerid=231522type%3D1%26q%3D%23' + title + '%23'
#这里只爬前几条微博里的id(第一页)
try: #程序保护,如果网页出现问题或别的报错跳过这次爬取
data = requests.get(url, headers=headers) # 请求数据
data = json.loads(data.text)
data = data['data'] if 'data' in data else {} # 找数据
items = data['cards'] if 'cards' in data else [] # 找存每条微博的列表
num += 1
print('爬了{}页的id'.format(num))
# 接下来是一步步找id的过程,就像将洋葱一层层拨开
for item in items:
#第一种情况,在card_group的0里
if 'card_group' in item:
id = item['card_group'] # 在item下找card_group
id = id[0] if id != [] else {} # 在card_group下找0
id = id['mblog'] if 'mblog' in id else {} # 在0下找mblog
id = id['id'] if 'id' in id else None ##在mblog下找id
if id != None:
id_list.append(id)
'''保险起见存id'''
with open('id.txt', 'a', encoding='utf-8') as file: # 在文件里续写
file.write(str(id) + '\n')
#第二种情况,在card_group的1里
elif 'card_group' in item:
id = item['card_group'] # 在item下找card_group
id = id[1] if id != [] else {} # 在card_group下找0
id = id['mblog'] if 'mblog' in id else {} # 在0下找mblog
id = id['id'] if 'id' in id else None ##在mblog下找id
if id != None:
id_list.append(id)
'''保险起见存id'''
with open('id.txt', 'a', encoding='utf-8') as file: # 在文件里续写
file.write(str(id) + '\n')
#第三种情况,直接在mblog里
elif 'mblog' in item:
id = item['mblog'] # 否则在item下找mblog
id = id['id'] if 'id' in id else None ##在hot_page下找id
if id != None:
id_list.append(id)
'''保险起见存id'''
with open('id.txt', 'a', encoding='utf-8') as file: # 在文件里续写
file.write(str(id) + '\n')
#还有别的情况就不写了,毕竟是少数,干脆不要了
else: pass
except: continue
file.close()
return id_list
#获取所有id微博的评论
# 这里用的是手机端的页面的headers
def get_comments(id_list):
headers = {
'user_agent': '用自己浏览器的',
'cookie': '用自己浏览器的',
}
num = 0 # 记录爬了多少次
for id in id_list: # 遍历每条微博
max_id = 0
while max_id != None:
try:
time.sleep(5) # 爬虫延时
url = 'https://m.weibo.cn/comments/hotflow?mid=' + str(id) + '&max_id=' + str(max_id)
txt = requests.get(url, headers=headers)
jsn = json.loads(txt.text)
data = jsn['data'] if 'data' in jsn else {} # 获取数据
items = data['data'] if 'data' in data else {} # 得到存数据的列表
max_id = data['max_id'] if 'max_id' in data else None # 得到max_id
# 判断是否爬取完,因为最后一次爬的评论的max_id=0,判断循环结束的条件是max_id=None,所以改一下
if max_id == 0:
max_id = None
with open('pl.txt', 'a', encoding='utf-8') as file: # 在文件里续写
for item in items: # 遍历列表每个评论
texts = item['text'] if 'text' in item else None # 找到评论文本
texts = re.sub('\<.*\>', ' ', texts) # 去除一些标签转译成的符号
file.write(texts + '\n')
num += 1
if num % 10 == 0:
print('爬了{}条评论'.format(num))
except: max_id = None
file.close()
if __name__ == '__main__':
hot_band_url = 'https://weibo.com/ajax/statuses/hot_band'
title_list = get_title(hot_band_url=hot_band_url)
id_list = get_id(title_list=title_list)
#id_list = []
#with open('id.txt', 'r') as file:
# for line in file.readlines():
# line = line.replace('\n', '')
# id_list.append(line)
get_comments(id_list)