1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| import requests from openpyxl import Workbook from openpyxl import load_workbook # import pymysql import pandas as pd
#请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36', 'Referer': 'https://m.weibo.cn/' }
# 定义函数获取多页数据,两个参数分别是下一页面的since_id和爬取的博主ID def get_page(since_id,bigV_id): #url变化的部分固定为传入的两个参数的字符串格式str() url = 'https://m.weibo.cn/api/container/getIndex?containerid=231068_-_QUESTIONLIST&extparam=' + str(bigV_id) + '&since_id=' + str(since_id) try: #获取页面的请求许可 response = requests.get(url, headers=headers) #如果请求返回状态码为200表示许可 if response.status_code == 200: #以json文件解析请求数据包 json = response.json() if json['ok'] == 1: #如果成功则获取json文件中的cardlistInfo下的since_id next_since_id = json.get('data').get('cardlistInfo')['since_id'] #返回下一页面的since return (json, next_since_id) else: return None #下面是出错退出返回 except requests.ConnectionError as e: print('Error', e.args)
#此代码定义函数run()来获取需要的数据,传入参数为需要爬取的微博用户 def run(bigV_id): # 创建一个新的Excel工作簿,设置列名称,和工作表名 newWb = Workbook() newWs = newWb.create_sheet('1', 0) # 添加表头 newWs.append(['uid', 'asker_id', 'name_ask', 'avatar', 'onlookers', 'brief_ques', 'value', 'detailed_url']) #设置一个值表示当前页面,初始为0 i = 0
# while True: while True: if i == 0: # 未滚动,当前为初始页面 #创建元组tuple_since_id存当前初始页面的数据 tuple_since_id = get_page('',bigV_id) # 页面加一 i+=1 #如果已经不是初始页面,开始数据搜集 else:
tuple_since_id = get_page(tuple_since_id[1],bigV_id)
if tuple_since_id: # 如果获取元组数据 print(tuple_since_id[1])
# 检查新的 since_id 是否为空,如果是,说明只有一个页面,只获取一次数据用break结束 if tuple_since_id[1] =='':#这里是单页面的条件,since_id='' #获取元组内的数据解析json json = tuple_since_id[0] # 解析JSON数据提取所需信息,我们需要的事data,card中的部分数据 cards = json['data']['cards'] #遍历card中的数据,挨个获取 for card in cards: #要的事card中的cardgroup的数据 if 'card_group' in card: row = [] # 建立一个价row的列表,用于存储合并后的一行数据 # 遍历cardgroup中的数据,挨个获取 for item in card['card_group']: #需要card_type==93下的数据 if item['card_type'] == 93: #获取user的id user = item['user'] if user:#如果获取到 #列表中的数据对应连续添加到Excel的列中,split是必要的内容切分只获取需要的 row.extend([bigV_id, user['id'], user['screen_name'], user['profile_image_url'], item['status'].split('</font><font')[0].split('>')[-1]]) else:#如果没有就置空 row.extend(['', '', '', '']) #下面同理也是获取card的数据 elif item['card_type'] == 8: row.extend([item['title_sub'], item['desc1'], item['scheme']]) print(item['title_sub']) newWs.append(row)#增加新的一行 print("一页的数据获取完毕,结束") #单页面的数据获取完毕,结束 break
#接下来就是获取需要滚动加载的多页面包的数据,逻辑一致,只是没有结束条件 else:
json = tuple_since_id[0] # 解析JSON数据提取所需信息 cards = json['data']['cards'] for card in cards: if 'card_group' in card: row = [] # 用于存储合并后的一行数据 for item in card['card_group']: if item['card_type'] == 93: user = item['user'] if user: row.extend([bigV_id,user['id'], user['screen_name'], user['profile_image_url'],item['status'].split('</font><font')[0].split('>')[-1]]) else: row.extend(['','','','']) elif item['card_type'] == 8: row.extend([item['title_sub'], item['desc1'], item['scheme']]) print(item['title_sub']) newWs.append(row)
else: break # 滚动到底跳出循环
#Excel表格保存save()函数,命名为用户名.xlsx newWb.save(str(bigV_id) + '.xlsx')
#main函数,说明这个工作表的路径和要处理的开始行 if __name__ == "__main__": file_path = r"./merged_file.xlsx"
# 读取Excel文件的第2行的第一列数据 df = pd.read_excel(file_path, usecols=[0], header=None) ids = df.iloc[305:350, 0].tolist() print(ids) #调用run()函数 # run(1990466285) #
# #调用run()函数 for id in ids: run(id)
|