scrapy 爬取微博(五)【最新超详细解析】: 爬取微博文章

1 读取配置参数

爬取微博文章首先需要读取settings.py中的设置的配置变量,然后编写爬虫,读取的配置变量主要有爬取的关键词、时间范围、爬取区域等。

class WeiboSearchSpider(scrapy.Spider):name = 'weibo_search'allowed_domains = ['weibo.com']settings = get_project_settings()keyword_list = settings.get('KEYWORD_LIST')if not isinstance(keyword_list, list):if not os.path.isabs(keyword_list):keyword_list = os.getcwd() + os.sep + keyword_listif not os.path.isfile(keyword_list):sys.exit('不存在%s文件' % keyword_list)keyword_list = utils.get_keyword_list(keyword_list)for i, keyword in enumerate(keyword_list):if len(keyword) > 2 and keyword[0] == '#' and keyword[-1] == '#':keyword_list[i] = '%23' + keyword[1:-1] + '%23'weibo_type = utils.convert_weibo_type(settings.get('WEIBO_TYPE'))contain_type = utils.convert_contain_type(settings.get('CONTAIN_TYPE'))regions = utils.get_regions(settings.get('REGION'))base_url = 'https://s.weibo.com'start_date = settings.get('START_DATE',datetime.now().strftime('%Y-%m-%d'))end_date = settings.get('END_DATE', datetime.now().strftime('%Y-%m-%d'))if utils.str_to_time(start_date) > utils.str_to_time(end_date):sys.exit('settings.py配置错误,START_DATE值应早于或等于END_DATE值,请重新配置settings.py')further_threshold = settings.get('FURTHER_THRESHOLD', 46)mysql_error = Falsepymysql_error = False

2 start_requests

负责发送请求的start_requests

  def start_requests(self):start_date = datetime.strptime(self.start_date, '%Y-%m-%d')end_date = datetime.strptime(self.end_date,'%Y-%m-%d') + timedelta(days=1)start_str = start_date.strftime('%Y-%m-%d') + '-0'end_str = end_date.strftime('%Y-%m-%d') + '-0'for keyword in self.keyword_list:if not self.settings.get('REGION') or '全部' in self.settings.get('REGION'):base_url = 'https://s.weibo.com/weibo?q=%s' % keywordurl = base_url + self.weibo_typeurl += self.contain_typeurl += '&timescope=custom:{}:{}'.format(start_str, end_str)print(f'url:{url}')yield scrapy.Request(url=url,callback=self.parse,meta={'base_url': base_url,'keyword': keyword})else:for region in self.regions.values():base_url = ('https://s.weibo.com/weibo?q={}&region=custom:{}:1000').format(keyword, region['code'])url = base_url + self.weibo_typeurl += self.contain_typeurl += '&timescope=custom:{}:{}'.format(start_str, end_str)# 获取一个省的搜索结果yield scrapy.Request(url=url,callback=self.parse,meta={'base_url': base_url,'keyword': keyword,'province': region})

3 parse

负责解析页面上元素的parse方法

 def parse(self, response):base_url = response.meta.get('base_url')keyword = response.meta.get('keyword')province = response.meta.get('province')is_empty = response.xpath('//div[@class="card card-no-result s-pt20b40"]')page_count = len(response.xpath('//ul[@class="s-scroll"]/li'))if is_empty:print('当前页面搜索结果为空')elif page_count < self.further_threshold:# 解析当前页面for weibo in self.parse_weibo(response):self.check_environment()yield weibonext_url = response.xpath('//a[@class="next"]/@href').extract_first()if next_url:next_url = self.base_url + next_urlyield scrapy.Request(url=next_url,callback=self.parse_page,meta={'keyword': keyword})else:start_date = datetime.strptime(self.start_date, '%Y-%m-%d')end_date = datetime.strptime(self.end_date, '%Y-%m-%d')while start_date <= end_date:start_str = start_date.strftime('%Y-%m-%d') + '-0'start_date = start_date + timedelta(days=1)end_str = start_date.strftime('%Y-%m-%d') + '-0'url = base_url + self.weibo_typeurl += self.contain_typeurl += '&timescope=custom:{}:{}&page=1'.format(start_str, end_str)# 获取一天的搜索结果yield scrapy.Request(url=url,callback=self.parse_by_day,meta={'base_url': base_url,'keyword': keyword,'province': province,'date': start_str[:-2]})

4 parse_weibo

解析微博内容

    def parse_weibo(self, response):"""解析网页中的微博信息"""keyword = response.meta.get('keyword')for sel in response.xpath("//div[@class='card-wrap']"):info = sel.xpath("div[@class='card']/div[@class='card-feed']/div[@class='content']/div[@class='info']")if info:weibo = WeiboItem()weibo['mid'] = sel.xpath('@mid').extract_first()bid = sel.xpath('.//div[@class="from"]/a[1]/@href').extract_first().split('/')[-1].split('?')[0]weibo['bid'] = bidweibo['user_id'] = info[0].xpath('div[2]/a/@href').extract_first().split('?')[0].split('/')[-1]weibo['screen_name'] = info[0].xpath('div[2]/a/@nick-name').extract_first()txt_sel = sel.xpath('.//p[@class="txt"]')[0]retweet_sel = sel.xpath('.//div[@class="card-comment"]')retweet_txt_sel = ''if retweet_sel and retweet_sel[0].xpath('.//p[@class="txt"]'):retweet_txt_sel = retweet_sel[0].xpath('.//p[@class="txt"]')[0]content_full = sel.xpath('.//p[@node-type="feed_list_content_full"]')is_long_weibo = Falseis_long_retweet = Falseif content_full:if not retweet_sel:txt_sel = content_full[0]is_long_weibo = Trueelif len(content_full) == 2:txt_sel = content_full[0]retweet_txt_sel = content_full[1]is_long_weibo = Trueis_long_retweet = Trueelif retweet_sel[0].xpath('.//p[@node-type="feed_list_content_full"]'):retweet_txt_sel = retweet_sel[0].xpath('.//p[@node-type="feed_list_content_full"]')[0]is_long_retweet = Trueelse:txt_sel = content_full[0]is_long_weibo = Trueweibo['text'] = txt_sel.xpath('string(.)').extract_first().replace('\u200b', '').replace('\ue627', '')weibo['article_url'] = self.get_article_url(txt_sel)weibo['location'] = self.get_location(txt_sel)if weibo['location']:weibo['text'] = weibo['text'].replace('2' + weibo['location'], '')weibo['text'] = weibo['text'][2:].replace(' ', '')if is_long_weibo:weibo['text'] = weibo['text'][:-4]weibo['at_users'] = self.get_at_users(txt_sel)weibo['topics'] = self.get_topics(txt_sel)reposts_count = sel.xpath('.//a[@action-type="feed_list_forward"]/text()').extract()reposts_count = "".join(reposts_count)try:reposts_count = re.findall(r'\d+.*', reposts_count)except TypeError:print("无法解析转发按钮,可能是 1) 网页布局有改动 2) cookie无效或已过期。\n""请在 https://github.com/dataabc/weibo-search 查看文档,以解决问题,")raise CloseSpider()weibo['reposts_count'] = reposts_count[0] if reposts_count else '0'comments_count = sel.xpath('.//a[@action-type="feed_list_comment"]/text()').extract_first()comments_count = re.findall(r'\d+.*', comments_count)weibo['comments_count'] = comments_count[0] if comments_count else '0'attitudes_count = sel.xpath('.//a[@action-type="feed_list_like"]/button/span[2]/text()').extract_first()attitudes_count = re.findall(r'\d+.*', attitudes_count)weibo['attitudes_count'] = attitudes_count[0] if attitudes_count else '0'created_at = sel.xpath('.//div[@class="from"]/a[1]/text()').extract_first().replace(' ', '').replace('\n', '').split('前')[0]weibo['created_at'] = utils.standardize_date(created_at)source = sel.xpath('.//div[@class="from"]/a[2]/text()').extract_first()weibo['source'] = source if source else ''pics = ''is_exist_pic = sel.xpath('.//div[@class="media media-piclist"]')if is_exist_pic:pics = is_exist_pic[0].xpath('ul[1]/li/img/@src').extract()pics = [pic[8:] for pic in pics]pics = [re.sub(r'/.*?/', '/large/', pic, 1) for pic in pics]pics = ['https://' + pic for pic in pics]video_url = ''is_exist_video = sel.xpath('.//div[@class="thumbnail"]//video-player').extract_first()if is_exist_video:video_url = re.findall(r'src:\'(.*?)\'', is_exist_video)[0]video_url = video_url.replace('&amp;', '&')video_url = 'http:' + video_url# if not retweet_sel:#     weibo['pics'] = pics#     weibo['video_url'] = video_url# else:#     weibo['pics'] = ''#     weibo['video_url'] = ''weibo['retweet_id'] = ''if retweet_sel and retweet_sel[0].xpath('.//div[@node-type="feed_list_forwardContent"]/a[1]'):retweet = WeiboItem()retweet['id'] = retweet_sel[0].xpath('.//a[@action-type="feed_list_like"]/@action-data').extract_first()[4:]retweet['bid'] = retweet_sel[0].xpath('.//p[@class="from"]/a/@href').extract_first().split('/')[-1].split('?')[0]info = retweet_sel[0].xpath('.//div[@node-type="feed_list_forwardContent"]/a[1]')[0]retweet['user_id'] = info.xpath('@href').extract_first().split('/')[-1]retweet['screen_name'] = info.xpath('@nick-name').extract_first()retweet['text'] = retweet_txt_sel.xpath('string(.)').extract_first().replace('\u200b','').replace('\ue627', '')retweet['article_url'] = self.get_article_url(retweet_txt_sel)retweet['location'] = self.get_location(retweet_txt_sel)if retweet['location']:retweet['text'] = retweet['text'].replace('2' + retweet['location'], '')retweet['text'] = retweet['text'][2:].replace(' ', '')if is_long_retweet:retweet['text'] = retweet['text'][:-4]retweet['at_users'] = self.get_at_users(retweet_txt_sel)retweet['topics'] = self.get_topics(retweet_txt_sel)reposts_count = retweet_sel[0].xpath('.//ul[@class="act s-fr"]/li[1]/a[1]/text()').extract_first()reposts_count = re.findall(r'\d+.*', reposts_count)retweet['reposts_count'] = reposts_count[0] if reposts_count else '0'comments_count = retweet_sel[0].xpath('.//ul[@class="act s-fr"]/li[2]/a[1]/text()').extract_first()comments_count = re.findall(r'\d+.*', comments_count)retweet['comments_count'] = comments_count[0] if comments_count else '0'attitudes_count = retweet_sel[0].xpath('.//a[@class="woo-box-flex woo-box-alignCenter woo-box-justifyCenter"]//span[@class="woo-like-count"]/text()').extract_first()attitudes_count = re.findall(r'\d+.*', attitudes_count)retweet['attitudes_count'] = attitudes_count[0] if attitudes_count else '0'created_at = retweet_sel[0].xpath('.//p[@class="from"]/a[1]/text()').extract_first().replace(' ', '').replace('\n', '').split('前')[0]retweet['created_at'] = utils.standardize_date(created_at)source = retweet_sel[0].xpath('.//p[@class="from"]/a[2]/text()').extract_first()retweet['source'] = source if source else ''# retweet['pics'] = pics# retweet['video_url'] = video_urlretweet['retweet_id'] = ''yield {'weibo': retweet, 'keyword': keyword}weibo['retweet_id'] = retweet['id']weibo["ip"] = self.get_ip(bid)avator = sel.xpath("div[@class='card']/div[@class='card-feed']/div[@class='avator']")if avator:user_auth = avator.xpath('.//svg/@id').extract_first()print(user_auth)if user_auth == 'woo_svg_vblue':weibo['user_authentication'] = '蓝V'elif user_auth == 'woo_svg_vyellow':weibo['user_authentication'] = '黄V'elif user_auth == 'woo_svg_vorange':weibo['user_authentication'] = '红V'elif user_auth == 'woo_svg_vgold':weibo['user_authentication'] = '金V'else:weibo['user_authentication'] = '普通用户'print(weibo)weibo['keywords'] = keywordyield {'weibo': weibo, 'keyword': keyword}

5 运行情况

我们爬取的关键词是:[‘华为’, ‘苹果公司’]
爬取的时间范围是:2024年9月1日~9月30日
运行效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完成UI界面的绘制

绘制UI 接上文&#xff0c;在Order90Canvas下创建Image子物体&#xff0c;图片资源ui_fish_lv1&#xff0c;设置锚点&#xff08;CountdownPanelImg同理&#xff09;&#xff0c;命名为LvPanelImg,创建Text子物体&#xff0c;边框宽高各50&#xff0c; &#xff0c;重名为LvT…

影刀---如何进行自动化操作

本文不是广告&#xff0c;没有人给我宣传费&#xff0c;只是单纯的觉得这个软件很好用 感谢大家的多多支持哦 本文 1.基本概念与操作&#xff08;非标准下拉框和上传下载&#xff09;非标准对话框的操作上传对话框、下载的对话框、提示的对话框 2.综合案例3.找不到元素怎么办&a…

css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis、::before的使用

1、~的使用直接看代码 <script setup> </script><template><div class"container"><p><a href"javascript:;">纪检委</a><a href"javascript:;">中介为</a><a href"javascript:…

架构师:消息队列的技术指南

1、简述 消息队列(Message Queue, MQ)是一种异步通信机制,允许系统的各个组件通过消息在彼此之间进行通信。消息队列通过解耦系统组件、缓冲高峰期请求和提高系统的可扩展性,成为分布式系统中不可或缺的一部分。 2、工作原理 消息队列的基本工作原理是生产者将消息发布到…

python爬虫案例——抓取链家租房信息(8)

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…

Axure-本地发布,局域网内用户访问

目录 前言内容一. 选择Axure发布路径&#xff0c;进行相应配置二.添加IIS服务配置&#xff08;不在这里赘述&#xff01;&#xff09;三&#xff1a;添加IIS配置&#xff0c;创建网站四.添加安全策略&#xff1a;实践&#xff1a; 前言 最近加入了公司的积分系统&#xff0c;由…

Qt网络编程——QUdpSocket

文章目录 Qt网络编程QUdpSocketUdp回显服务器Udp客户端 Qt网络编程 网络编程本质上是写应用层代码&#xff0c;需要传输层提供支持。 而传输层最核心的协议就是UDP和TCP&#xff0c;这两个协议有较大差别&#xff0c;所以Qt提供了两套API。 要是有Qt网络编程的API&#xff0…

【CSS Tricks】css动画详解

目录 引言一、动画关键帧序列二、动画各属性拆解1. animation-name2. animation-duration3. animation-delay3.1 设置delay为正值3.2 设置delay为负值 4. animation-direction5. animation-iteration-count6. animation-fill-mode7. animation-play-state8. animation-timing-f…

Kubernetes云原生存储解决方案之 Rook Ceph实践探究

Kubernetes云原生存储解决方案之 Rook Ceph实践探究 除了手动部署独立的 Ceph 集群并配置与Kubernetes进行对接外&#xff0c;Rook Ceph 支持直接在 Kubernetes 集群上部署 Ceph 集群。 通过Rook Ceph云原生存储编排平台&#xff0c;使得 Kubernetes 集群中启用高可用的 Ceph…

RabbitMQ常用管理命令及管理后台

RabbitMQ管理命令 1、用户管理1.1、新增一个用户1.2、查看当前用户列表1.3、设置用户角色1.4、设置用户权限1.5、查看用户权限 2、RabbitMQ的web管理后台2.1、查看rabbitmq 的插件列表2.2、启用插件2.3、禁用插件2.4、访问RabbitMQ的web后台2.4、通过web页面新建虚拟主机 ./rab…

【计算机网络】详解HTTP请求和响应格式常见请求方法Header报头响应报文状态码URL

一、HTTP协议的定义 在互联网世界中&#xff0c;HTTP &#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个至关重要的协议。它定义了客户端&#xff08;如浏览器&#xff09;与服务器之间如何通信&#xff0c;以交换或传输超文本&#xff08…

如何选择合适的跨境网络专线?

选择合适的跨境网络专线对于保障企业的国际业务顺畅运行至关重要。以下是一些选择跨境网络专线时可以参考的关键点&#xff1a; 服务商的信誉和经验&#xff1a;首先考察服务商的市场声誉和行业经验。一个好的服务商应该拥有良好的客户评价和成功案例&#xff0c;这表明他们有能…

【4.5】图搜索算法-BFS和DFS求岛屿的最大面积

一、题目 给定一个包含了一些 0 和 1 的非空二维数组 grid 。一个岛屿是由一些相邻的 1 (代表土地)构成的组合&#xff0c; 这里的「相邻」要求两个1必须在水 平或者竖直方向上相邻 。你可以假设 grid 的四个边缘都被0&#xff08;代表水&#xff09;包围着。 找到给定的二维…

4.数据结构与算法-线性表的顺序表示和实现

2.1 线性表的定义和特点 线性表例子 线性表的逻辑特征 2.2 案例引入 案例2.1 案例2.1&#xff1a;一元多项式的运算 案例2.2&#xff1a;系数多项式的运算 用时间换取空间--线性数组相对链式访问速度快 但这种方法链式更节省空间&#xff0c;所以用时间换取空间 案例2.3&…

Hbase要点简记

Hbase要点简记 Hbase1、底层架构2、表逻辑结构 Hbase HBase是一个分布式的、列式的、实时查询的、非关系型数据库&#xff0c;可以处理PB级别的数据&#xff0c;吞吐量可以到的百万查询/每秒。主要应用于接口等实时数据应用需求&#xff0c;针对具体需求&#xff0c;设计高效率…

Arm Linux 交叉编译openssl 1.1.1

一、openssl 源码下载 OpenSSL的官方网站或源代码仓库下载最新或指定版本的OpenSSL源代码。 官网地址&#xff1a; https://openssl-library.org/source/index.html 旧版本下载&#xff1a; https://openssl-library.org/source/old/index.html 这里以 1.1.1 为例 国内git…

plt.bar函数介绍及实战

目录 plt.bar() 函数实战 plt.bar() 函数 plt.bar() 函数是 Matplotlib 中用于创建柱状图的函数。它用于在图形中绘制一个或多个柱状图&#xff0c;通常用于展示类别型数据的数量或大小的比较。 基本语法&#xff1a; plt.bar(x, height, width0.8, bottomNone, aligncenter…

归并排序,外排序,计数排序(非比较排序)

归并排序&#xff1a;&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序…

大模型(LLM) 是仅仅比 模型(Model) 更大吗?

我们日常经常提到模型 model&#xff0c;大模型LLM&#xff0c;大家都知道这两者之间的区别和联系吗&#xff1f; 只是如下图这样&#xff0c;大小的区别吗&#xff1f;下面我们对模型model和大模型LLM进行解释和描述 什么是模型&#xff1f; 模型是机器学习中一个核心概念&a…

[Docker学习笔记]Docker的原理Docker常见命令

文章目录 什么是DockerDocker的优势Docker的原理Docker 的安装Docker 的 namespaces Docker的常见命令docker version:查看版本信息docker info 查看docker详细信息我们关注的信息 docker search:镜像搜索docker pull:镜像拉取到本地docker push:推送本地镜像到镜像仓库docker …