爬虫实战:利用代理ip爬取推特网站数据

引言

亮数据-网络IP代理及全网数据一站式服务商屡获殊荣的代理网络、强大的数据挖掘工具和现成可用的数据集。亮数据:网络数据平台领航者https://www.bright.cn/?promo=RESIYEAR50/?utm_source=brand&utm_campaign=brnd-mkt_cn_csdn_yingjie202502

在跨境电商、社交媒体运营以及数据采集的过程中,我们经常会遇到被平台拦截的问题。这是因为各大平台为了保护其正常业务,防止恶意攻击或数据滥用,会限制非人类用户的访问频率。如果我们使用多账号登录或通过自动化工具频繁访问平台,系统很容易识别出异常行为,进而将我们的账号或IP地址列入黑名单,导致访问受限或直接被封禁。这种情况不仅影响了业务的正常开展,还可能导致数据采集中断,甚至丢失重要信息。面对这一问题,目前最有效的解决方案之一是使用动态IP。动态IP的核心优势在于,每次访问时都可以切换到一个新的IP地址,从而降低被平台识别和拦截的概率。与传统的商业数据中心IP不同,动态IP中有一类特殊的动态住宅IP,它们来自真实的家庭网络,能够更好地模拟普通用户的上网行为。

通过使用动态住宅IP服务,我们可以在进行社交媒体数据采集时,大幅减少被平台拦截的风险。无论是跨境电商的竞品分析,还是社交媒体运营的数据监控,动态住宅IP都能为我们提供更加稳定和高效的访问环境。接下来,我们将详细介绍如何配置和使用动态住宅IP服务,完成社交平台的数据采集工作。

准备

首先我们需要配置动态住宅IP,我问了一下AI,推荐了几家常见的服务商,意义了解之后,我发现亮数据平台正好在促销,性价比是几家中最高的,这次我们就来试用一下。只需要注册账号即可开始使用。登录以后会跳转到工作台,在这里点击获取代理。

之后要进行简单的配置,这里我们只需要填写名称就可以了,其他选项大家可以根据需求选择。

动态住宅代理的计费模式是按照流量计算,使用期间可以随时切换IP地址。

配置好以后建议安装一下,这样可以提高安全性。当然不安装也不会太大的影响,后面需要的时候还可以再安装。

这样就配置好了。在这个页面可以找到我们的主机地址、用户名和密码,旁边有一个样例程序,可以修改它称为我们的爬虫程序。

配置好就可以开始配置社交平台API接口了。在平台中注册为开发者就可以拿到自己的token,在后面的访问需要使用它才能正常接入。

采集社交媒体数据

接下来就可以制作爬虫程序。首先我们需要将服务的参数设置好。

proxies = {
  'http': 'http://brd-customer-hl_a0a48734-zone-residential proxy1:9270yrzw8wyb@brd.superproxy.io:33335'
  'https': 'https://brd-customer-hl_a0a48734-zone-residential proxy1:9270yrzw8wyb@brd.superproxy.io:33335'
}

我们本次的任务是抓取下图账号的所有帖子和每个帖子点赞数、转发数等指标。在开始之前,我们需要配置一下请求头参数,这个可以直接在网站中获得。在控制台中找到header和cookie的值复制出来就可以了。

找到之后把它们打包在一个类中方便后面使用。

class CsxqTwitterKeywordSearch:
    def __init__(self,saveFileName,cookie_str):
        self.saveFileName = saveFileName
        self.searchCondition = None
        self.headers = {
        'headers对应的参数'
        }
        self.cookies = self.cookie_str_to_dict(cookie_str)

接下来我们需要配置一下请求参数,这些需要通过cursor去网站获取。

def get_params(self,cursor):
    if cursor == "":
        variables = {"rawQuery": self.searchCondition, "count": 20,"querySource": "typed_query", "product": "Latest"}
        params = {
            "variables": json.dumps(variables,separators=(",",":")),
            "features": ""
        }
    else:
        variables = {"rawQuery": self.searchCondition, "count": 20, "cursor": cursor, "querySource": "typed_query", "product": "Latest"}
        params = {
            "variables":  json.dumps(variables,separators=(",",":")),
            "features": ""
        }
    return params

之后使用获取到的参数访问并获取元数据,这里需要注意元数据是一个json表单。这里url部分需要将中间替换为自己的token 才能使用。

def get(self,cursor):
    self.headers["x-csrf-token"] = self.cookies['ct0']
    url = "https://x.com/i/api/graphql/6uoFezW1o4e-n-VI5vfksA/SearchTimeline"
    params = self.get_params(cursor)
    while True:
        try:
            response = requests.get(url,
                                    headers=self.headers,
                                    cookies=self.cookies,
                                    params=params,
                                    timeout=(3,10),
			proxies=proxies)
            if response.status_code == 429:
                time.sleep(60*20)
            if response.status_code == 200:
                data = response.json()
                return data
        except Exception as e:
            print("搜索接口发生错误:%s" % e)

最后我们需要将目标数据从获取到的元数据中提取出来。这里我们需要提取的是内容、时间点赞评论转发用户名简介粉丝量关注量,由于元数据是json表单所以只需要简单转换为字典就可以轻松获取。

def parse_data(self,entries):
    resultList = []
    def transTime(dd):
        GMT_FORMAT = '%a %b %d %H:%M:%S +0000 %Y'
        timeArray = datetime.datetime.strptime(dd, GMT_FORMAT)
        return timeArray.strftime("%Y-%m-%d %H:%M:%S")
 
    contentList = []
    for index, ent in enumerate(entries):
        try:
            entryId = ent.get('entryId', "")
 
            if 'tweet' in entryId:
                l_result = ent['content']['itemContent']['tweet_results']['result'] if ent['content'].get(
                    'itemContent') else None
                if l_result:
                    contentList.append(l_result)
            elif "profile-conversation" in entryId:
                items = ent['content']['items']
                for i in items:
                    l_result = i['item']['itemContent']['tweet_results']['result'] if i['item'].get(
                        'itemContent') else None
                    if l_result:
                        contentList.append(l_result)
        except:
            pass
    for l in contentList:
        try:
            result = l.get('tweet') if l.get('tweet') else l
            legacy = result['legacy']
            core = result['core']
            created_at = transTime(legacy.get('created_at'))
            full_text = legacy.get('full_text')
            note_tweet = result.get('note_tweet')
            favorite_count = legacy.get('favorite_count')  # 点赞
            reply_count = legacy.get('reply_count')  # 回复
            retweet_count = legacy.get('retweet_count', 0)
            quote_count = legacy.get('quote_count', 0)
            retweet_count = retweet_count + quote_count
            if note_tweet:
                try:
                    full_text = note_tweet['note_tweet_results']['result']['text']
                except:
                    pass
 
            u_legacy = core['user_results']['result']['legacy']
            hash_uname = u_legacy.get('screen_name')
            description = u_legacy['description']
            friends_count = u_legacy['friends_count']
            followers_count = u_legacy.get('followers_count')
 
            item = {"内容":full_text,"时间": created_at,"点赞":favorite_count,"评论":reply_count,"转发":retweet_count,"用户名": hash_uname,"简介": description,\
                    "粉丝量":followers_count,"关注量":friends_count}
            print("数据->",item)
            resultList.append(item)
        except:
            pass
    self.save_data(resultList)

最后我们要将数据保存为一个本地csv文件。

def save_data(self, resultList):
    if resultList:
        df = pd.DataFrame(resultList)
        if not os.path.exists(f'./{self.saveFileName}.csv'):
            df.to_csv(f'./{self.saveFileName}.csv', index=False, mode='a', sep=",", encoding="utf_8_sig")
        else:
            df.to_csv(f'./{self.saveFileName}.csv', index=False, mode='a', sep=",", encoding="utf_8_sig",
                      header=False)
        self.resultList = []
        print("保存成功")

整个流程通过一个入口函数控制,在运行的同时打印一些状态信息。

def run(self,word):
    cursor = ""
    page = 1
    while True:
        # if page > 2:
        #     break
        print("正在爬取的页数:%s,cursor:%s"%(page,cursor))
        resqJson = self.get(cursor)
        if not resqJson:
            break
        cursor,entries = self.get_cursor(resqJson)
        if entries:
            self.parse_data(entries)
            page += 1
        else:
            break
def main(self,fromDate,endDate):
 
    wordList = ["climate change"]
 
    start = 0
    for index,word in enumerate(wordList[start:],start):
        self.searchCondition = f"{word} lang:en until:{endDate} since:{fromDate}"
        print("搜索条件:",self.searchCondition)
        self.run(word)
 

通过一个主函数执行整个程序,这里需要用户粘贴自己的cookie。

if __name__ == '__main__':
    cookie_str = '改成你自己的cookies'
    fromDate = "2024-08-10"
    endDate = "2024-10-13"
    saveFileName= "Tim_Cook"
    ctks = CsxqTwitterKeywordSearch(saveFileName,cookie_str)
    ctks.main(fromDate,endDate)

运行一下就可以获得结果,可以看到程序运行正常。

总结

上面的实战演示展示了配置动态住宅IP和社交平台API接口的方法,并演示了如何制作爬虫程序进行数据采集包括设置参数、配置请求头和请求参数、获取元数据、提取目标数据以及将数据保存为本地CSV文件,通过粘贴自己的cookie即可运行程序。在这一过程中我们也看到了动态住宅IP的作用,在大量采集数据的时候,通过使用动态住宅IP服务,可以有效减少被平台识别和拦截的概率不仅提高了数据采集的效率,还增强了隐匿性,从而更好地规避平台的限制。于此同时我们也测试了亮数据产品的可靠性,不论是在易用性和产品的丰富性上都有独到之处。不仅如此,亮数据还有一些爬虫工具可供使用,

粉丝福利

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#windows窗体人脸识别

一、创建一个数据库,名为TestFaceDB 里面有一张表就OK了,表名Users,表里面有几个字段我说明一下: id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------v…

opencv中minAreaRect函数输出角度问题

opencv中minAreaRect函数输出角度问题 新版opencv中minAreaRect函数计算最小外接矩形时,角度范围由旧版的[-90, 0]变为[0, 90]。 cv2.minAreaRect输入:四边形的四个点(不要求顺序)。 输出:最小外接矩形的中心点坐标x…

Eclipse:关闭多余的工具条

Eclipse默认的工具条非常多,可以通过如下方法选择关闭一些不常用的: 1.选择菜单Window -> Perspective -> Customize Perspective 2.根据需要勾选Toolbar Visbility下面的工具条项

电商小程序(源码+文档+部署+讲解)

引言 随着移动互联网的快速发展,电商小程序成为连接消费者与商家的重要桥梁。电商小程序通过数字化手段,为消费者提供了一个便捷、高效的购物平台,从而提升购物体验和满意度。 系统概述 电商小程序采用前后端分离的架构设计,服…

MySQL单表存多大的数据量比较合适

前言 经常使用MySQL数据库的小伙伴都知道,当单表数据量达到一定的规模以后,查询性能就会显著降低。因此,当单表数据量过大时,我们往往要考虑进行分库分表。那么如何计算单表存储多大的数据量合适?当单表数据达到多大的…

Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件

步骤1 开始通过 WSL 使用 VS Code | Microsoft Learn 点击远程开发扩展包。 步骤2 Remote Development - Visual Studio Marketplace 点击install, 允许打开Visual Studio Code。 步骤3 共有4项,一齐安装。 步骤4 在WSL Linux(Ubuntu)中&#xf…

微服务SpringCloud Alibaba组件nacos教程【详解naocs基础使用、服务中心配置、集群配置,附有案例+示例代码】

一.Nacos教程 文章目录 一.Nacos教程1.1 Nacos简介1.2 nacos基本使用直接下载打包服务源码方式启动 1.3 创建nacos客服端1.4 nacos集群配置1.5 nacos配置中心 1.1 Nacos简介 nacos是spring cloud alibaba生态中非常重要的一个组件,它有两个作用: 1:注册…

2024年终总结和2025年规划

2024年的主线是AI基础的学习和读书,虽然AI学习花费了更多的时间,但是读书长久看来于我是更重要的事情,哈哈哈,因此先简单回顾一下读书记忆,回顾我的2024,再展望一下我的2025. 我的2024年记忆 读万卷书&am…

实时云渲染:驱动XR技术产业化腾飞的核心引擎

在科技飞速发展的当下,扩展现实(XR)技术正以前所未有的速度融入人们的生活与工作,为用户打造出沉浸式逼真的虚拟环境。据知名XR媒体XR Today的最新数据显示,2024年全球XR市场规模已突破500亿美元,预计到202…

【AI编程】体验a0.dev:专为移动端app的对话式AI编程工具

摘要 体验专为移动端APP开发的AI编程工具 a0.dev,并附上实践过程和价格说明 体验a0.dev:专为移动端app的对话式AI编程工具 最近在探索新的AI编程工具时,发现了a0.dev,一个专注于移动端应用开发的对话式AI编程工具。今天就和大家分…

基于若依开发的工程项目管系统开源免费,用于工程项目投标、进度及成本管理的OA 办公开源系统,非常出色!

一、简介 今天给大家推荐一个基于 RuoYi-Flowable-Plus 框架二次开发的开源工程项目管理系统,专为工程项目的投标管理、项目进度控制、成本管理以及 OA 办公需求设计。 该项目结合了 Spring Boot、Mybatis、Vue 和 ElementUI 等技术栈,提供了丰富的功能…

数据库数据恢复—MongoDB丢失_mdb_catalog.wt文件导致报错的数据恢复案例

MongoDB数据库存储模式为文档数据存储库,存储方式是将文档存储在集合之中。 MongoDB数据库是开源数据库,同时提供具有附加功能的商业版本。 MongoDB中的数据是以键值对(key-value pairs)的形式显示的。在模式设计上,数据库受到的约束更少。这…

小米 R3G 路由器(Pandavan)实现网络打印机功能

小米 R3G 路由器(Pandavan)实现网络打印机功能 一、前言 家中有多台 PC 设备需要打印服务,但苦于家中的 Epson L380 打印机没有网络打印功能,并且配置 Windows 共享打印机实在是过于繁琐且需要共享机保持唤醒状态过于费电。想到…

笔记8——模式匹配 match语句(仅在Python 3.10及以上版本中可用)

文章目录 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用)基本语法基本匹配操作应用场景 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用) Python 3.10 及以上版本中才引入了 match 语句用于简化复杂的条件判断和数据解构;类似于其他语言中的 swit…

Edge浏览器清理主页

我们都知道,Microsoft Edge浏览器是微软创造的搜索浏览器,Windows10、11自带。但是你可以看到,每次你打开Edge浏览器的时候都可以看到许多的广告,如图: 导致打开Edge浏览器的时候会遭受卡顿,广告骚扰&#…

JVM类加载和垃圾回收(详细)

文章目录 JVM介绍JDK/JRE/JVM的关系 内存结构堆程序计数器虚拟机栈本地方法栈本地内存 类文件字节码文件结构 类加载类的生命周期加载类加载器双亲委派模型 链接初始化类卸载 垃圾回收堆空间的基本结构内存分配和回收原则死亡对象判断方法垃圾收集算法垃圾收集器 JVM 介绍 JD…

算法——结合实例了解深度优先搜索(DFS)

一,深度优先搜索(DFS)详解 DFS是什么? 深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树、图的算法。其核心思想是尽可能深地探索分支,直到无法继续时回溯到上一个节点…

[c语言日寄]在不完全递增序中查找特定要素

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…

计算机视觉-局部特征

一、局部特征 1.1全景拼接 先用RANSAC估计出变换,就可以拼接两张图片 ①提取特征 ②匹配特征 ③拼接图像 1.2 点的特征 怎么找到对应点?(才能做点对应关系RANSAC) :特征检测 我们希望找到的点具有的特征有什么特…

实践记录-NAS入手前后的记录-关于设备选型的练习

快速回顾 知道nas是干啥的不,你买这东西准备干啥?你准备花多少预算啊?在配置性能/价格/需求之间做个取舍和平衡;看看设备到底怎么样?入手体验如何? 参考来源 服务器和网络设备的技术方案设计和设备选型的…