鱼C论坛

 找回密码
 立即注册
查看: 1417|回复: 2

爬取微博网页不断出现重复,可赏分

[复制链接]
发表于 2021-11-25 20:12:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我使用以下代码,爬取微博网页,但是运行时产生的结果不断重复前三十个话题,我认为是这部分代码出了问题,希望有大佬能帮助一下。
这是我使用的代码
  1. # -*- coding: utf-8 -*-
  2. import requests,random,re
  3. import time
  4. import os
  5. import csv
  6. import sys
  7. import json
  8. import importlib
  9. from fake_useragent import UserAgent
  10. from lxml import etree

  11. importlib.reload(sys)
  12. startTime = time.time() #记录起始时间

  13. #--------------------------------------------文件存储-----------------------------------------------------
  14. path = "E:\DESKTOP\wenbenwajuewenjianjia\weiboComments.csv"
  15. csvfile = open(path, 'a', newline='', encoding = 'utf-8-sig')
  16. writer = csv.writer(csvfile)
  17. #csv头部
  18. writer.writerow(('话题链接','话题内容','楼主ID', '楼主昵称', '楼主性别','发布日期',
  19.                  '发布时间', '转发量','评论量','点赞量', '评论者ID', '评论者昵称',
  20.                  '评论者性别', '评论日期', '评论时间','评论内容'))

  21. #设置heades
  22. headers = {
  23.     'Cookie': '_T_WM=22822641575; H5_wentry=H5; backURL=https%3A%2F%2Fm.weibo.cn%2F; ALF=1584226439; MLOGIN=1; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5RJaVYrb.BEuOvUQ8Ca2OO5JpX5K-hUgL.FoqESh-7eKzpShM2dJLoIp7LxKML1KBLBKnLxKqL1hnLBoMceoBfeh2EeKBN; SCF=AnRSOFp6QbWzfH1BqL4HB8my8eWNC5C33KhDq4Ko43RUIzs6rjJC49kIvz5_RcOJV2pVAQKvK2UbAd1Uh6j0pyo.; SUB=_2A25zQaQBDeRhGeBM71cR8SzNzzuIHXVQzcxJrDV6PUJbktAKLXD-kW1NRPYJXhsrLRnku_WvhsXi81eY0FM2oTtt; SUHB=0mxU9Kb_Ce6s6S; SSOLoginState=1581634641; WEIBOCN_FROM=1110106030; XSRF-TOKEN=dc7c27; M_WEIBOCN_PARAMS=oid%3D4471980021481431%26luicode%3D20000061%26lfid%3D4471980021481431%26uicode%3D20000061%26fid%3D4471980021481431',
  24.     'Referer': 'https://m.weibo.cn/detail/4312409864846621',
  25.     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36',
  26.     'X-Requested-With': 'XMLHttpRequest'
  27. }

  28. #-----------------------------------爬取战疫情首页的每个主题的ID------------------------------------------
  29. comments_ID = []
  30. def get_title_id():
  31.     for page in range(1,4):  #每个页面大约有18个话题
  32.         headers = {
  33.             "User-Agent" : UserAgent().chrome #chrome浏览器随机代理
  34.         }
  35.         time.sleep(1)
  36.         #该链接通过抓包获得
  37.         api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=' + str(page)
  38.         print(api_url)
  39.         rep = requests.get(url=api_url, headers=headers)
  40.         #获取ID值并写入列表comment_ID中
  41.         for json in rep.json()['data']['statuses']:
  42.             comment_ID = json['id']
  43.             comments_ID.append(comment_ID)

  44. #-----------------------------------爬取战疫情每个主题的详情页面------------------------------------------         
  45. def spider_title(comment_ID):
  46.     try:
  47.         article_url = 'https://m.weibo.cn/detail/'+ comment_ID
  48.         print ("article_url = ", article_url)
  49.         html_text = requests.get(url=article_url, headers=headers).text
  50.         #话题内容
  51.         find_title = re.findall('.*?"text": "(.*?)",.*?', html_text)[0]
  52.         title_text = re.sub('<(S*?)[^>]*>.*?|<.*? />', '', find_title) #正则匹配掉html标签
  53.         print ("title_text = ", title_text)
  54.         #楼主ID
  55.         title_user_id = re.findall('.*?"id": (.*?),.*?', html_text)[1]
  56.         print ("title_user_id = ", title_user_id)
  57.         #楼主昵称
  58.         title_user_NicName = re.findall('.*?"screen_name": "(.*?)",.*?', html_text)[0]
  59.         print ("title_user_NicName = ", title_user_NicName)
  60.         #楼主性别
  61.         title_user_gender = re.findall('.*?"gender": "(.*?)",.*?', html_text)[0]
  62.         print ("title_user_gender = ", title_user_gender)
  63.         #发布时间
  64.         created_title_time = re.findall('.*?"created_at": "(.*?)".*?', html_text)[0].split(' ')
  65.         #日期
  66.         if 'Mar' in created_title_time:
  67.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '03', created_title_time[2])
  68.         elif 'Feb' in created_title_time:
  69.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '02', created_title_time[2])
  70.         elif 'Jan' in created_title_time:
  71.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '01', created_title_time[2])
  72.         elif 'Apr' in created_title_time:
  73.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '04', created_title_time[2])
  74.         elif 'May' in created_title_time:
  75.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '05', created_title_time[2])
  76.         elif 'Jun' in created_title_time:
  77.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '06', created_title_time[2])
  78.         elif 'Jul' in created_title_time:
  79.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '07', created_title_time[2])
  80.         elif 'Aug' in created_title_time:
  81.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '08', created_title_time[2])
  82.         elif 'Sep' in created_title_time:
  83.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '09', created_title_time[2])
  84.         elif 'Oct' in created_title_time:
  85.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '10', created_title_time[2])
  86.         elif 'Nov' in created_title_time:
  87.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '11', created_title_time[2])
  88.         elif 'Dec' in created_title_time:
  89.             title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '12', created_title_time[2])
  90.         else:
  91.             print ('该时间不在疫情范围内,估计数据有误!URL = ')
  92.             pass
  93.         print ("title_created_YMD = ", title_created_YMD)

  94.         #发布时间
  95.         add_title_time = created_title_time[3]
  96.         print ("add_title_time = ", add_title_time)
  97.         #转发量
  98.         reposts_count = re.findall('.*?"reposts_count": (.*?),.*?', html_text)[0]
  99.         print ("reposts_count = ", reposts_count)
  100.         #评论量
  101.         comments_count = re.findall('.*?"comments_count": (.*?),.*?', html_text)[0]
  102.         print ("comments_count = ", comments_count)
  103.         #点赞量
  104.         attitudes_count = re.findall('.*?"attitudes_count": (.*?),.*?', html_text)[0]
  105.         print ("attitudes_count = ", attitudes_count)   
  106.         comment_count = int(int(comments_count) / 20) #每个ajax一次加载20条数据
  107.         position1 = (article_url, title_text, title_user_id, title_user_NicName,title_user_gender, title_created_YMD, add_title_time, reposts_count, comments_count, attitudes_count, " ", " ", " ", " "," ", " ")
  108.         #写入数据
  109.         writer.writerow((position1))
  110.         return comment_count
  111.     except:
  112.         pass


  113. #-------------------------------------------------抓取评论信息---------------------------------------------------
  114. #comment_ID话题编号
  115. def get_page(comment_ID, max_id, id_type):
  116.     params = {
  117.         'max_id': max_id,
  118.         'max_id_type': id_type
  119.     }
  120.     url = ' https://m.weibo.cn/comments/hotflow?id={}&mid={}&max_id'.format(comment_ID, comment_ID)
  121.     try:
  122.         r = requests.get(url, params=params, headers=headers)
  123.         if r.status_code == 200:
  124.             return r.json()
  125.     except requests.ConnectionError as e:
  126.         print('error', e.args)
  127.         pass

  128. #-------------------------------------------------抓取评论item最大值---------------------------------------------------
  129. def parse_page(jsondata):
  130.     if jsondata:
  131.         items = jsondata.get('data')
  132.         item_max_id = {}
  133.         item_max_id['max_id'] = items['max_id']
  134.         item_max_id['max_id_type'] = items['max_id_type']
  135.         return item_max_id

  136. #-------------------------------------------------抓取评论信息---------------------------------------------------
  137. def write_csv(jsondata):
  138.     for json in jsondata['data']['data']:
  139.         #用户ID
  140.         user_id = json['user']['id']
  141.         # 用户昵称
  142.         user_name = json['user']['screen_name']
  143.         # 用户性别,m表示男性,表示女性
  144.         user_gender = json['user']['gender']
  145.         #获取评论
  146.         comments_text = json['text']
  147.         comment_text = re.sub('<(S*?)[^>]*>.*?|<.*? />', '', comments_text) #正则匹配掉html标签
  148.         # 评论时间
  149.         created_times = json['created_at'].split(' ')
  150.         if 'Feb' in created_times:
  151.             created_YMD = "{}/{}/{}".format(created_times[-1], '02', created_times[2])
  152.         elif 'Jan' in created_times:
  153.             created_YMD = "{}/{}/{}".format(created_times[-1], '01', created_times[2])
  154.         else:
  155.             print ('该时间不在疫情范围内,估计数据有误!')
  156.             pass
  157.         created_time = created_times[3] #评论时间时分秒
  158.         #if len(comment_text) != 0:
  159.         position2 = (" ", " ", " ", " "," ", " ", " ", " ", " ", " ", user_id, user_name, user_gender, created_YMD, created_time, comment_text)
  160.         writer.writerow((position2))#写入数据
  161.         #print (user_id, user_name, user_gender, created_YMD, created_time)   


  162. #-------------------------------------------------主函数---------------------------------------------------
  163. def main():
  164.     count_title = len(comments_ID)
  165.     for count, comment_ID in enumerate(comments_ID):
  166.         print ("正在爬取第%s个话题,一共找到个%s话题需要爬取"%(count+1, count_title))
  167.         #maxPage获取返回的最大评论数量
  168.         maxPage = spider_title(comment_ID)
  169.         print ('maxPage = ', maxPage)
  170.         m_id = 0
  171.         id_type = 0
  172.         if maxPage != 0: #小于20条评论的不需要循环
  173.             try:
  174.                 #用评论数量控制循环
  175.                 for page in range(0, maxPage):
  176.                     #自定义函数-抓取网页评论信息
  177.                     jsondata = get_page(comment_ID, m_id, id_type)
  178.                     
  179.                     #自定义函数-写入CSV文件
  180.                     write_csv(jsondata)
  181.                     
  182.                     #自定义函数-获取评论item最大值
  183.                     results = parse_page(jsondata)
  184.                     time.sleep(1)
  185.                     m_id = results['max_id']
  186.                     id_type = results['max_id_type']              
  187.             except:
  188.                 pass
  189.         print ("--------------------------分隔符---------------------------")
  190.     csvfile.close()
  191.    
  192. if __name__ == '__main__':
  193.    
  194.     #获取话题ID
  195.     get_title_id()
  196.    
  197.     #主函数操作
  198.     main()
  199.    
  200.     #计算使用时间
  201.     endTime = time.time()
  202.     useTime = (endTime-startTime) / 60
  203.     print("该次所获的信息一共使用%s分钟"%useTime)
复制代码



这是我认为有问题的部分

  1. comments_ID = []
  2. def get_title_id():
  3.     for page in range(1,477):  #每个页面大约有18个话题
  4.         headers = {
  5.             "User-Agent" : UserAgent().chrome #chrome浏览器随机代理
  6.         }
  7.         time.sleep(1)
  8.         #该链接通过抓包获得
  9.         api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=' + str(page)
  10.         print(api_url)
  11.         rep = requests.get(url=api_url, headers=headers)
  12.         #获取ID值并写入列表comment_ID中
  13.         for json in rep.json()['data']['statuses']:
  14.             comment_ID = json['id']
  15.             comments_ID.append(comment_ID)
复制代码

结果放在图片里,不断地重复那几个网页
(怎么用鱼币悬赏感谢啊我不会)

运行结果

运行结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-11-25 20:13:40 | 显示全部楼层
还有那个URL里   /api/feed   是哪里来的,希望大佬解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-25 20:24:57 | 显示全部楼层
赤龙将 发表于 2021-11-25 20:13
还有那个URL里   /api/feed   是哪里来的,希望大佬解答

建议使用vsode或者pyharm编写代码,然后i可以单步执行,同时可以看到每一步时所有变量的值,这总问题一般都可以通过这样的方式解决
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 20:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表