Twitter 用户推文时间线爬虫

article/2025/11/7 21:24:00

0x00 前言

上篇分享了如何申请到Twitter api,申请到twitter API后就可以进行爬虫啦!这里分享一下如何使用API对用户推文时间线爬虫

Twitter 是有分享如何使用API爬虫的python代码的,但是具体如何使用,以及各种参数如何设置需要用户自己去配置,这里分享一下如何设置和使用其中爬取用户推文的部分。

0x01 具体步骤

Twitter-API-v2-coda Github地址:https://github.com/twitterdev/Twitter-API-v2-sample-code

详解部分为:Twitter-API-v2-sample-code-main/User-Tweet-Timeline/user-tweets.py

1.首先在twitter developer platform:https://developer.twitter.com/en/apply-for-access 注册一个APP

在这里插入图片描述
2. 代码分析
在这里插入图片描述
代码中bearer_token:上图中2位置的token 就是bearer_token部分,直接粘贴在代码就OK,注意保存这个token,因为下一次打开就是新的token啦。

在这里插入图片描述

这部分中,user_id很好理解,在其中输入你要爬取的用户ID即可,爬取多个用户就改成一个list.

url部分可操作性很多,这是我设置的url.更多可以参考:https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/introduction

url ="<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100&exclude=retweets&start_time=2021-05-01T00:00:01Z&end_time=2021-06-01T00:00:01Z".format(user_id,tweet_fields)
#max_results:最大返回数,最多能返回的tweets数
#exclude=retweets:排除转发的推文
#start_time,end_time :起止时间
#tweet_fields:get_params中获取,但是要得到两个返回值的话,需要改成我下面设置的格式使用
url = "<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100&pagination_token={}&exclude=retweets&start_time=2021-05-01T00:00:01Z&end_time=2021-06-01T00:00:01Z".format(user_id, tweet_fields,pagination_token)
#pagination_token:获取到的推文>返回的最大值时,会产生一个pagination_token,即获取下一页。

在这里插入图片描述

get_params,可选你要爬取的部分,但是要注意格式,比如我要获取的内容有hasttags,mentions,urls,reply count,retweet count,favorite count. 这些内容在public_metrics,emtities 中可以获得 。注:两个返回值需要改成tweet_fields = “"而不是原来的“tweet_fields ”: "

tweet_fields = "tweet.fields=public_metrics,entities"

Twitter 有一份参考说明可以找到要找到的内容在哪里:https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/introduction

在这里插入图片描述

这部分不用改,就是调用了上面的bearer_token,以及说明了是用v2版本的API

后面直接运行他的代码就可以得到你想要的值啦,

0x02 源码分享

附我对这个代码进行的一些改动可获得推文的id,content,hasttags_count,mentions_count,urls_count,reply_count,retweet_count,favorite_count.

并存储在csv文件中或Mysql数据库中。

#use twitter api
import time
import requests
import threading
import random
import pandas as pddef __init__(self,keyword):threading.Thread.__init__(self)self.keyword = keywordself.bearer_token = 'AAAAAAAAAAAAAAAAAAAAAOHKRwEAAAAAXF5NOvPXXUPATBLLo12cvyhKOl4%3D75zRjigC4imC02b0gP3l1ily5QAcRkyMQt1UHbM4JE5xQ6Jq5i'self.next_token = ""
# To set your environment variables in your terminal run the following line:
# export 'BEARER_TOKEN'='<your_bearer_token>'def create_url(self,id):# Replace with user ID belowuser_id =   id# return "<https://api.twitter.com/2/users/{}/tweets>".format(user_id)tweet_fields = "tweet.fields=public_metrics,entities"# print(tweet_fields)# print("<https://api.twitter.com/2/users/{}/tweets?{>}".format(user_id,tweet_fields))#url:+except,time->&exclude=retweets&start_time=2021-08-14T00:00:01Z&end_time=2021-08-28T00:00:01Zif self.next_token == "":#***************change time here********************url ="<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100&exclude=retweets&start_time=2021-05-01T00:00:01Z&end_time=2021-06-01T00:00:01Z".format(user_id,tweet_fields)# url = "<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100".format(user_id,tweet_fields)#&exclude=retweets&start_time=2020-10-1T00:00:01Z&end_time=2021-10-1T00:00:01Zelse:pagination_token = self.next_tokenurl = "<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100&pagination_token={}&exclude=retweets&start_time=2021-05-01T00:00:01Z&end_time=2021-06-01T00:00:01Z".format(user_id, tweet_fields,pagination_token)# "<https://api.twitter.com/2/users/{}/tweets?{>}&max_results=100&pagination_token={}&exclude=retweets&start_time=2020-10-1T00:00:01Z&end_time=2021-10-1T00:00:01Z"return urldef get_id(self):#注释掉的这部分为从数据库中调取id# id = []# db = mysql.connector.connect(host='localhost', user='root', password='000000', port=3306, db='FindBOT',auth_plugin='mysql_native_password')# cursor = db.cursor()# try:#     cursor.execute("select * from %s" % (self.keyword) + "_bot_list where (mark = '0')")#     results = cursor.fetchall()#     for row in results:#         if row[4] == 0:#             id.append(row[0])#             try:#                 cursor.execute("update %s" % (self.keyword) + "_bot_list set mark = '1' where id ='%s '" % (row[0]))#                 db.commit()#             except  Exception as e:#                 traceback.print_exc(e)#                 db.rollback()#                 print("defalt update")# except Exception as e:#     traceback.print_exc(e)#     db.rollback()#     print("defalt select")# db.close()# ***************change bot/user id here********************#从csv文件中获取id listpath = "your path"df = pd.read_csv(path)ids = list(df['id'])marks = list(df['mark'])dict_results = dict(zip(ids, marks))id = list(filter(lambda ids: dict_results[ids] < 1, ids))return iddef bearer_oauth(self,r):"""Method required by bearer token authentication."""r.headers["Authorization"] = f"Bearer {self.bearer_token}"r.headers["User-Agent"] = "v2UserTweetsPython"return rdef connect_to_endpoint(self,url):proxies = {"http": "<http://127.0.0.1:7890>", "https": "<http://127.0.0.1:7890>", }# 这里设置了一个代理,因为国内可能连不上,但是不用好像也可以爬出来。response = requests.request("GET", url, auth=self.bearer_oauth,  proxies=proxies)if response.status_code != 200:raise Exception("Request returned an error: {} {}".format(response.status_code, response.text))return response.json()#entities_feature get one page feature(max_results)
def entities_feature(self,response):id = []content = []hashtags_count = []mentions_count = []urls_count = []hashtags = []mentions = []urls = []like = []reply = []retweet = []try:for i in range(0,len(response['data'])):id .append(response['data'][i]['id'])content.append(str((response['data'][i]['text'])))if response['data'][i]['public_metrics']  :like.append(response['data'][i]['public_metrics']['like_count'])reply.append(response['data'][i]['public_metrics']['reply_count'])retweet.append(response['data'][i]['public_metrics']['retweet_count'])else:like.append(0)reply.append(0)retweet.append(0)continuehashtag_str = ""mention_str = ""url_str = ""if 'entities' not in response['data'][i].keys():hashtags.append("null")mentions.append("null")urls.append("null")hashtags_count.append(0)mentions_count.append(0)urls_count.append(0)continueelse:entities = response['data'][i]['entities']if 'hashtags' in entities:hashtags_count.append(len(response['data'][i]['entities']['hashtags']))for j in range(0, len(response['data'][i]['entities']['hashtags'])):if j < len(response['data'][i]['entities']['hashtags']) - 1:hashtag_str += response['data'][i]['entities']['hashtags'][j]['tag'] + ";"else:hashtag_str += response['data'][i]['entities']['hashtags'][j]['tag']hashtags.append(hashtag_str)else:hashtags_count.append(0)hashtags.append("null")if 'mentions' in entities:mentions_count.append(len(response['data'][i]['entities']['mentions']))for j in range(0, len(response['data'][i]['entities']['mentions'])):if j < len(response['data'][i]['entities']['mentions']) - 1:mention_str += response['data'][i]['entities']['mentions'][j]['username'] + ";"else:mention_str += response['data'][i]['entities']['mentions'][j]['username']mentions.append(mention_str)else:mentions_count.append(0)mentions.append("null")if 'urls' in entities:urls_count.append(len(response['data'][i]['entities']['urls']))for j in range(0,len(response['data'][i]['entities']['urls'])) :if j < len(response['data'][i]['entities']['urls'])-1:url_str += response['data'][i]['entities']['urls'][j]['url'] +";"else:url_str += response['data'][i]['entities']['urls'][j]['url']urls.append(url_str)else:urls_count.append(0)urls.append("null")except :print("*"*30)# print(response)data = []for i in range(0,len(id)) :data.append([id[i],content[i],retweet[i],reply[i],like[i],hashtags_count[i],mentions_count[i],urls_count[i],hashtags[i],mentions[i],urls[i]])return datadef save_data(self,data):#此次可该为Mysql数据库存储# for a in data:#     db = mysql.connector.connect(host='localhost', user='root', password='000000', port=3306, db='FindBOT',#                                  auth_plugin='mysql_native_password', charset="utf8mb4")#     cursor = db.cursor()#     try:#         cursor.execute(#             "INSERT IGNORE INTO %s" % self.keyword + "_bot_tweets ( id,content,retweet_count,reply_count,favorite_count,hashtags_count,mentions_count,urls_count,hashtags,mentions,urls) VALUES ('%s',\\'%s\\','%d','%d','%d','%d','%d','%d','%s','%s','%s')" % (#                 a[0], escape_string(a[1]), a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]))#         db.commit()#         # print("success")#     except mysql.connector.Error as err:#         print("****************************************")#         print(a)#         print("Something went wrong: {}".format(err))#         print("****************************************")#         # traceback.print_exc(e)#         db.rollback()# db.close()# ***************change save csv here********************df = pd.read_csv('51_61.csv')haven_id = list(df['id'])haven_content = list(df['content'])haven_retweet_count = list(df['retweet_count'])haven_reply_count = list(df['reply_count'])haven_favorite_count = list(df['favorite_count'])haven_hashtags_count = list(df['hashtags_count'])haven_mentions_count = list(df['mentions_count'])haven_urls_count = list(df['urls_count'])for a in data :if a[0] in haven_id :continueelse:haven_id.append(a[0])haven_content.append(a[1])haven_retweet_count.append(a[2])haven_reply_count.append(a[3])haven_favorite_count.append(a[4])haven_hashtags_count.append(a[5])haven_mentions_count.append(a[6])haven_urls_count.append(a[7])# marks = [1]*len(haven_id) mark是我用来标记用户的。没啥用marks = list(df['mark'])data = {'id': haven_id, 'mark': marks,'content':haven_content,'retweet_count':haven_retweet_count,'reply_count':haven_reply_count,'favorite_count':haven_favorite_count,'hashtags_count':haven_hashtags_count,'mentions_count':haven_mentions_count,'urls_count':haven_urls_count}df = pd.DataFrame(data)# ***************change save csv here********************df.to_csv('**.csv', index=False)def get_feature(self,url):json_response = self.connect_to_endpoint(url)feature = self.entities_feature(json_response)# print(json.dumps(json_response, indent=1, sort_keys=True))if 'next_token' in json_response['meta'].keys():self.next_token = json_response['meta']['next_token']else:self.next_token = ""return featuredef run(self) :ids =self.get_id()for id in ids :try:print(id)url = self.create_url(id)print(url)feature = self.get_feature(url)print(feature)while self.next_token != "" :next_feature = []new_url =self.create_url(id)next_feature = self.get_feature(new_url)for value in next_feature :feature.append(value)if feature == []:#+logcontinueelse:self.save_data(feature)time.sleep(sleeptime)except:# +logcontinue
if **name** == '**main**':
crawl_by_api("china").run()

0x03 一些闲话

本人创建了一个公众号,分享科研路上的小问题,新发现,欢迎关注公众号,给我留言!!!
一起奋发向上,攻克难题吧~~

在这里插入图片描述


http://chatgpt.dhexx.cn/article/auHK6gom.shtml

相关文章

twitter注册不了_如何阻止Twitter重点阻止不相关的通知

twitter注册不了 Social networks are always trying to get you to “engage” more with their service and recently, Twitter has introduced a new trick: Highlights notifications. 社交网络一直在努力让您与他们的服务“互动”&#xff0c;最近&#xff0c;Twitter引入…

语义识别

文章目录 前言二、案例1.《大雪阳沈东北》2.《青成城山都》 结论 前言 我是个话说逻不辑混乱的&#xff0c;长短对话经常别人听不被懂。短句慢说却是交流无碍&#xff0c;例如“回吃饭家”&#xff0c;“灶房在烧火”。以下测试了下百度和360能否听懂我说话&#xff0c;测试内…

语义搜索

语义搜索简介 目录 语义搜索简介 文档检索 vs. 数据检索 语义模型 语义数据搜索 语义Web——数据Web 利用链接数据进行搜索 存储和索引 (Semplore) 排序原则 如何将排序紧密结合到基本操作中? ​ 从DBpedia收集的混合的查询数据集 为图结构数据(RDF)建立结构…

自然语言处理NLP(10)——语义分析

在上一部分中&#xff0c;我们介绍了句法分析中的局部句法分析以及依存关系分析&#xff08;自然语言处理NLP&#xff08;9&#xff09;——句法分析c&#xff1a;局部句法分析、依存关系分析&#xff09;&#xff0c;至此&#xff0c;繁复冗长的句法分析部分就结束了。 在这一…

语义网络 - 语义网络

语义网络 - 语义网络 编辑本段 回目录 语义网络 - 正文 用于表示知识和建立认知模型的一种带标号的有向图。在语义网络中&#xff0c;带标号的节点表示思考对象──具体事物、抽象概念、状态和局势等&#xff1b;带标号的有向弧则表示节点所代表对象间的关系。语义网络中每一条…

语义表示法

思路方案 在安全领域的研究中我们发现&#xff0c;很多数据预处理的步骤&#xff0c;在不同的场景下中都可以相互 借鉴&#xff0c;甚至可以进行直接复用。例如&#xff0c;对于加密流量相关的数据&#xff0c;当算法工程师 获取到一批加密流量的 pcap 包之后&#xff0c;不论他…

语义网

语义网&#xff08;Semantic Web&#xff09;是对未来网络的一个设想&#xff0c;现在与Web 3.0这一概念结合在一起&#xff0c;作为3.0网络时代的特征之一。简单地说&#xff0c;语义网是一种智能网络&#xff0c;它不但能够理解词语和概念&#xff0c;而且还能够理解它们之间…

四、语义分析

在经过了词法和语法分析后&#xff0c;能够表明该源程序在书写上是没有语法错误的&#xff0c;因此可以开始进行翻译。采用的方法是语法制导翻译。 语法制导翻译 为每个产生式配上一个翻译子程序&#xff0c;如果使用过JavaCC就可以很清楚地理解这个意思了&#xff0c;在每个…

语义信息概述

什么叫语义信息&#xff1f; 无论在图像&#xff0c;文本&#xff0c;语音处理领域等&#xff0c;我们常看到一个词&#xff0c;“语义信息”。 维基百科中的解释&#xff1a; 语义信息&#xff08;英语&#xff1a;semantic information&#xff09;在传媒行业指语言文字提供…

传统补间动画的制作

实验性质&#xff1a;设计性试验 一、实验目的&#xff1a;掌握元件的制作方法&#xff1b;掌握用元件来制作传统补间动画&#xff1b;掌握淡入淡出效果的制作&#xff1b;掌握色彩变换动画效果的制作&#xff1b;掌握加速减速运动动画的制作&#xff1b;多个对象同时运动。 …

Android动画的使用——补间动画

基础知识 谈起 Android动画&#xff0c;我们就得讲讲他的分类&#xff1a;从大的方向来说主要分为两类&#xff1a;View动画&#xff08;视图动画&#xff09;和 属性动画。其中 View动画又包括 补间动画 和 帧动画。其中&#xff0c;补间动画 使用广泛&#xff0c;下面我们一…

An动画优化之补间形状与传统补间的优化

文章目录 一、补间形状的优化&#xff08;1&#xff09;准备工作1&#xff09;写字2&#xff09;画圆3&#xff09;标明 &#xff08;2&#xff09;创建关键帧及动画1&#xff09;创建关键帧2&#xff09;创建补间形状3&#xff09;改变速度 &#xff08;3&#xff09;效果 二、…

Android studio 动画---补间动画

1、新建文件。【注意&#xff1a;文件名只能命名为anim】 2、新建文件 3、在新建的文件中添加代码&#xff1a;【以下代码仅供参考】 3.1、改变动画的透明度&#xff1a; <?xml version"1.0" encoding"utf-8"?> <set xmlns:android"http:/…

动画三部曲--补间动画

图片从慢慢退出&#xff0c;过程中通过缩放、渐变等实现动画效果 将缩放的参数写入xml 中&#xff0c;translate_animation.xml <translatexmlns:android"http://schemas.android.com/apk/res/android"android:fromXDelta"0"android:fromYDelta"…

Android 补间动画原理

这段时间项目中用到了动画&#xff0c;所以趁热打铁&#xff0c;看看动画原理 补间动画 使用举例 TranslateAnimation translateAnim new TranslateAnimation(0, 100, 0, 100);translateAnim.setDuration(1000);translateAnim.setFillAfter(true);testBut.startAnimation(t…

补间动画和逐帧动画

补间动画 补间&#xff08;Tween&#xff09;动画通过对View进行一系列的图形变换来实现动画效果&#xff0c;其中图像变换包括平移、缩放、旋转、改变透明度等。补间动画最常用的方式是通过XML文件定义动画。 透明度渐变动画&#xff08;AlphaAnimation&#xff09; 主要通…

Android 动画—补间动画

帧动画是通过连续播放图片来模拟动画效果&#xff0c;而补间动画开发者只需指定动画开始&#xff0c;以及动画结束"关键帧"&#xff0c;而动画变化的"中间帧"则由系统计算并补齐&#xff01; 1.补间动画的分类和Interpolator Andoird所支持的补间动画效果…

【Android】补间动画用法最全详解

本文目录 补间动画概述和分类各类补间动画实现xml实现补间动画透明度动画-AlphaAnimation缩放动画-ScaleAnimation位移动画-TranslateAnimation旋转动画-RotateAnimation动画组合-AnimationSet 代码实现补间动画透明度动画&#xff08;AlphaAnimation&#xff09;缩放动画&…

补间动画详解一 基类Animation

补间动画(Tween animation)是通过在两个关键帧之间补充渐变的动画效果来实现的。 Android系统提供了四个补间动画的类,分别是AlphaAnimation、RotateAnimation、ScaleAnimation和TranslateAnimation,另外还有一个能够把多个动画组合起来的AnimationSet类,这些类都有一个共…

Android动画之补间动画

Android动画之补间动画 和上面一章学的帧动画不同&#xff0c;帧动画 是通过连续播放图片来模拟动画效果&#xff0c;而补间动画开发者只需指定动画开始&#xff0c;以及动画结束"关键帧"&#xff0c; 而动画变化的"中间帧"则由系统计算并补齐&#xff01…