下午好,
我对Python很陌生,但我正在尝试编写一个允许我下载所有帖子的代码(包括"笔记") 从指定的Tumblr帐户到我的电脑。
鉴于我没有编码经验,我试图找到一个预制的脚本,这将允许我这样做。我在GitHub上找到了几个精彩的脚本,但是没有一个真正从Tumblr帖子中返回笔记(据我所见,尽管如果有人知道那个,那么请纠正我。)。
因此,我试着编写自己的脚本。我在下面的代码中取得了一些成功。它打印出来自给定Tumblr的最新20个帖子(尽管格式相当丑陋 - 基本上数百行文本都打印在记事本文件的一行中):
#This script prints all the posts (including tags, comments) and also the
#first 20notes from all the Tumblr blogs.
import pytumblr
# Authenticate via API Key
client = pytumblr.TumblrRestClient('myapikey')
#offset = 0
# Make the request
client.posts('staff', limit=2000, offset=0, reblog_info=True, notes_info=True,
filter='html')
#print out into a .txt file
with open('out.txt', 'w') as f:
print >> f, client.posts('staff', limit=2000, offset=0, reblog_info=True,
notes_info=True, filter='html')
但是,我希望脚本能够持续打印帖子,直到它到达指定博客的末尾。
我搜索了这个网站,发现了一个非常相似的问题(Getting only 20 posts returned through PyTumblr),已经被stackoverflow用户戳回答了。但是,我似乎无法实际实施poke的解决方案,以便它适用于我的数据。实际上,当我运行以下脚本时,根本不会产生任何输出。
import pytumblr
# Authenticate via API Key
client = pytumblr.TumblrRestClient('myapikey')
blog = ('staff')
def getAllPosts (client, blog):
offset = 0
while True:
posts = client.posts(blog, limit=20, offset=offset, reblog_info=True, notes_info=True)
if not posts:
return
for post in posts:
yield post
offset += 20
我应该注意到这个网站上有几篇关于Tumblr笔记的帖子(例如Getting more than 50 notes with Tumblr API),其中大多数都询问如何为每个帖子下载超过50个笔记。我非常满意每篇文章只有50个笔记,这是我希望增加的帖子数量。
另外,我已经将这篇文章标记为Python,但是,如果有更好的方法来获取我需要使用其他编程语言的数据,那就更好了。
非常感谢你的时间!
答案 0 :(得分:3)
第二个代码片段是一个逐个生成帖子的生成器,所以你必须将它作为循环的一部分使用,然后对输出做一些事情。这是您的代码,其中包含一些额外的代码,这些代码遍历生成器并打印出它返回的数据。
import pytumblr
def getAllPosts (client, blog):
offset = 0
while True:
posts = client.posts(blog, limit=20, offset=offset, reblog_info=True, notes_info=True)
if not posts:
return
for post in posts:
yield post
offset += 20
# Authenticate via API Key
client = pytumblr.TumblrRestClient('myapikey')
blog = ('staff')
# use the generator getAllPosts
for post in getAllPosts(client, blog):
print(post)
但是,该代码中有一些错误。 getAllPosts
不会仅仅发布每个帖子,它也会返回其他内容,因为它将遍历API响应,正如您在此示例中看到的,我在ipython
shell中运行。
In [7]: yielder = getAllPosts(client, 'staff')
In [8]: next(yielder)
Out[8]: 'blog'
In [9]: next(yielder)
Out[9]: 'posts'
In [10]: next(yielder)
Out[10]: 'total_posts'
In [11]: next(yielder)
Out[11]: 'supply_logging_positions'
In [12]: next(yielder)
Out[12]: 'blog'
In [13]: next(yielder)
Out[13]: 'posts'
In [14]: next(yielder)
Out[14]: 'total_posts'
这是因为posts
中的getAllPosts
对象是一个字典,其中不仅包含来自staff
博客的每篇帖子 - 它还包含博客包含的帖子数量等项目,博客的描述,上次更新等等。代码原样可能会导致无限循环,因为以下条件:
if not posts:
return
由于响应结构,永远不会成为现实,因为来自pytumblr
的空Tumblr API响应如下所示:
{'blog': {'ask': False,
'ask_anon': False,
'ask_page_title': 'Ask me anything',
'can_send_fan_mail': False,
'can_subscribe': False,
'description': '',
'followed': False,
'is_adult': False,
'is_blocked_from_primary': False,
'is_nsfw': False,
'is_optout_ads': False,
'name': 'asdfasdf',
'posts': 0,
'reply_conditions': '3',
'share_likes': False,
'subscribed': False,
'title': 'Untitled',
'total_posts': 0,
'updated': 0,
'url': 'https://asdfasdf.tumblr.com/'},
'posts': [],
'supply_logging_positions': [],
'total_posts': 0}
if not posts
将针对该结构进行检查,而不是posts
字段(此处为空列表),因此条件永远不会失败,因为响应字典不为空(请参阅: Truth Value Testing in Python)。
这里的代码(主要经过测试/验证)修复了getAllPosts
实现中的循环,然后使用该函数检索帖子并将其转储到名为(BLOG_NAME)-posts.txt
的文件中。
import pytumblr
def get_all_posts(client, blog):
offset = 0
while True:
response = client.posts(blog, limit=20, offset=offset, reblog_info=True, notes_info=True)
# Get the 'posts' field of the response
posts = response['posts']
if not posts: return
for post in posts:
yield post
# move to the next offset
offset += 20
client = pytumblr.TumblrRestClient('secrety-secret')
blog = 'staff'
# use our function
with open('{}-posts.txt'.format(blog), 'w') as out_file:
for post in get_all_posts(client, blog):
print >>out_file, post
# if you're in python 3.x, use the following
# print(post, file=out_file)
这只是API的帖子回复的直接文本转储,所以如果你需要使它看起来更好或任何东西,那取决于你。