【笔记】使用Twitter API V2进行数据爬取的经验总结

写在最前面:这篇笔记主要是基于自己使用API过程中遇到的问题以及不断的尝试形成的经验总结,所有内容都是一个字一个字敲的,所以还挺辛苦的。不过也正是因为这只是一些个人经验的归纳,所以对于API的函数和功能也会存在理解不到位的情况,还请谅解嘿嘿~当然也欢迎讨论交流!

主要参考链接:

目录

使用Twitter API抓取数据的基础知识

Response对象

Tweet对象

User对象

常用参数说明

StreamingClient

Pagination


在正式进行数据爬取之前,有两件基本的事情要做

Step 1: 获取 API Key and Secret, Bearer Token, Access Token and Secret。申请API的流程网上已经有很多分享了,这里就不再赘述。大致过程类似于(详细步骤)申请twitter api - 注册推特网站 - 实验室设备网 (zztongyun.com)

Step 2:判断是否需要使用streaming来进行爬虫

  • 流数据(Streaming data): 数千个数据源持续生成的数据,通常也同时以数据记录的形式发送
  • 流数据的处理适用于持续生成动态新数据的大多数场景

如果选择不使用streaming进行爬虫,不需要爬实时数据,就可以选择使用一般的Client类进行爬虫。如果选择使用stream进行爬虫,在Twitter API V2的场景下就主要会使用到StreamingClient这个类,当然有可能也需要使用到StreamResponse,StreamRule等。

使用Twitter API抓取数据的基础知识

不论是使用哪种数据抓取的方式,有几个关键知识是最好先提前了解的。只针对于获取数据的get相关函数而言,常用到的参数包括expansions, max_results,几类fields,以及query。返回的通常为Response对象。

Response对象

get函数返回的通常为Response对象,包含的object常用的为user或者tweet对象。其他object的类型还有Spaces,Lists,Media,Polls,Places。完整的各个object包含的信息可以在Twitter API v2 data dictionary | Docs | Twitter Developer Platform 中对应的链接中查看。

如果需要在返回的top-level object(例如user或tweet)之外,还想要返回其他object的信息,可以通过expansion或者几类fields的的参数进行指定。需要注意的是,在Respnose中返回的第一个对象是top-level object,其余指定返回的对象信息包含在includes里面。

这里主要给出最常用的Tweets和Users对象的使用方法整理

Tweet对象

Tweets对象是User,Media,Polls,Places的parent object,也是Twitter的基础模块之一。

Tweet对象的返回默认值为:id,text。其余可能会经常用的值还有author_id,conversation_id,created_at,lang等等。完整的表格可以见Tweet object | Docs | Twitter Developer Platform

在返回对象为users的函数中,可以通过expansions=pinned_tweet_id获得Tweet的默认值;同样在返回对象为tweet的函数中,通过expansions=referenced_tweets.id也可以获得tweet的默认值。除此之外,如果还需要返回更多tweet的值,可以在函数的tweet_fields参数中指定。

此处需要注意的是,按照参数说明指定返回的内容在直接print出Response对象的时候可能并不能直接看到。例如,

tweet = client.get_tweet(id, expansions=["author_id"],
                        tweet_fields=["public_metrics"],
                        user_fields=["description", "public_metrics", "location", "verified"])

此时返回的结果大致为(为了保护用户信息,没有给出真实返回的信息)

Response(data=<Tweet id=XXXXXXXXXXX text='XXXXXXXX'>, includes={'users': [<User id=xxxxxxxx name=XXXXXXX username=XXXX1234>]}, errors=[], meta={})

可以看到,返回的结果中包含的data部分是tweet类型的对象,includes部分包含的是user对象,但是此时user对象的内容仅包含id,name和username的默认参数,并没有我们指定的tweet_field以及user_field的其他参数。

这个时候对于附加参数的读取可以采用

# tweeet_fields中的public_metrics指定的是tweet的属性,会随着tweet对象在data部分返回
print(tweet.data.public_metrics) 

# user_fields中指定的参数在includes部分,取值的时候有一个‘[0]’是因为返回的user对象是发推文的用户,只存在一个用户,为了取出这唯一一个user的对象,就需要取数组的有且唯一一个元素
print(tweet.includes['users'][0].description)
print(tweet.includes['users'][0].public_metrics)
print(tweet.includes['users'][0].location)
print(tweet.includes['users'][0].verified)

User对象

user对象返回的默认值为id,name,username。其他常用的值还包括created_at, description等。完整的表格见User object | Docs | Twitter Developer Platform

通常user对象可以在相关的get函数中返回,也可以在返回tweet对象的get函数中额外返回。其中如果只使用expansions=author_id或者expansions=in_reply_to_user_id的话,额外返回的user信息只会包含user对象的默认值。除此之外,如果还需要返回更多user的值,可以在函数的user_fields参数中指定。

常用参数说明

  • expansions:我对于expansions的理解是,通过对expansions的指定,可以快速返回不同场景下fields对应的默认值,如果需要返回除了默认值以外的信息,还是需要通过相关的fields参数进行指定。对于tweet和user对象而言,常用的expansions参数设置为

    • tweet:
      • expansions=referenced_tweets.id
      • expansions=pinned_tweet_id
    • user:
      • expansions=author_id
      • expansions=entities.mentions.username
      • expansions=in_reply_to_user_id
      • expansions=referenced_tweets.id.author_id

    其他的expansions设置可以在Expansions and Fields — tweepy 4.12.1 documentation中查看。

  • max_results:通常最大值为100

  • 几类fields:media_fields,place_fields,poll_fields,tweet_fields,user_fields。**在不使用fields这个参数时,请求返回的对象只包括top-level的object以及expansions里面提到的objects,如果需要返回其他fields的数据,可以在对应的media_fields,place_fields,poll_fields,tweet_fields,user_fields中指定。其中同样较为常用的也是tweet_fields和user_fields,相关的信息可以查看对应object中包含的值。

  • query:尤其在search tweets相关的函数中,需要通过查询的条件获取满足条件的tweets,此时默认的参数就是query。query的基础规则和操作符可以参见https://developer.twitter.com/en/docs/tutorials/building-powerful-enterprise-filters/understand-the-basics。类似的规则还会用在filter或者rule相关的函数中

StreamingClient

可以参考Streaming — tweepy 4.12.1 documentation中的使用流程介绍敲代码,个人觉得在使用StreamingClient抓取数据时可能会使用到的代码基础框架如下:

from tweepy import StreamingClient


class IDPrinter(tweepy.StreamingClient):

    def on_tweet(self, tweet):
        print(tweet.id)


stream = StreamingClient(bearer_token=bearer_token, return_type=dict, wait_on_rate_limit=True)
printer = IDPrinter("Bearer Token here")
printer.sample()

上述代码完成的基本功能是:输出实时发布的tweet的id。

  • 若需要输出更多信息,可以在on_tweet中结合Client类的函数进行数据的输出和搜索。
  • 若需要对流数据进行筛选,主要可以使用以下三个函数完成:
    • streaming_client.add_rules(tweepy.StreamRule("Tweepy"))
    • streaming_client.filter()
  • 此外,为了增加流数据处理过程中的错误处理能力,可以在class IDPrinter中增加例如on_connection_error(self)函数,更多的函数和参数说明可以在Tweepy使用文档的StreamingClient部分查看。

Pagination

在大多数API函数的调用中都会存在着返回结果最大数量的限制,即max_results。这意味着,我们在一次请求中只能最多获得例如一个用户最新发表100条推文。但如果我们想要获取这个用户的所有推文,且不想原基于函数的pagination_token逐页的请求结果返回的话,就可以考虑使用API提供的另一个更为直接的功能模块Pagination。

class tweepy.Paginator(self, method, *args, limit=inf, pagination_token=None, **kwargs)

当被传递的方法返回的响应是 requests.Response 类型时,它将被反序列化来解析分页标记。意思就是,通过对函数中‘method’的指定,我们可以将所有的结果按照指定页的大小进行按页数的分割。这样就可以通过对一次性请求返回的对象进行迭代读取,获取每一页的内容逐页提取推文信息。

具体使用方法如下:

paginator = tweepy.Paginator(client.get_users_followers, id=xxxxx, max_results=200)

for page in paginator:
	.....

其余参数和功能可以参考官方文档进行尝试:Pagination — tweepy 4.12.1 documentation

以上!!

  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为了爬取淘宝笔记本电脑销量前500的数据,你可以使用 Python 的 requests 库和 BeautifulSoup 库。以下是示例代码,供你参考: ``` import requests from bs4 import BeautifulSoup import pandas as pd # 设置请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} # 设置URL和参数 url = 'https://s.taobao.com/search' params = { 'q': '笔记本电脑', # 搜索关键字 'sort': 'sale-desc', # 按销量从高到低排序 's': '1', # 开始页码 'bcoffset': '0', # 偏移量 'ntoffset': '0', # 偏移量 'p4ppushleft': '1%2C48', # 页码显示 'sadv': '0', # 是否高级筛选 'ajax': 'true', # 是否异步加载 } # 爬取数据 data = [] for page in range(1, 11): # 爬取前10页数据 params['s'] = str((page - 1) * 44) response = requests.get(url, params=params, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') items = soup.find_all('div', class_='item J_MouserOnverReq ') for item in items: name = item.find('div', class_='title').text.strip() price = item.find('div', class_='price g_price g_price-highlight').text.strip() sales = item.find('div', class_='deal-cnt').text.strip() data.append({'name': name, 'price': price, 'sales': sales}) # 转换为数据框 df = pd.DataFrame(data) # 处理数据 df['price'] = df['price'].str.replace('¥', '').astype(float) df['sales'] = df['sales'].str.replace('人付款', '').astype(int) # 按销量排序,取前500个 df = df.sort_values('sales', ascending=False).head(500) # 输出结果 print(df.head()) ``` 在此示例中,我们使用了 requests 库发送 HTTP 请求,并使用 BeautifulSoup 库解析 HTML 响应。我们使用了 URL 和参数来指定搜索关键字和排序方式。我们爬取了前10页数据,每页44个商品,共计440个商品,并将结果存储在一个列表中。我们将结果转换为 Pandas 数据框,并对价格和销量进行了处理。最后,我们按销量排序,取前500个,并输出结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值