60行代码实现分享到微博,QQ空间,豆瓣 - 介绍好用的Faraday

因为项目需要在后台实现自动将内容同时分享到微博,QQ空间,豆瓣等各个社交网络,一开始准备找个现成的gem,发现了hooopo写的:
[url]https://github.com/hooopo/oauth_china[/url] 但是这个项目微博用的是OAuth 1,新浪很快就不支持了,原准备fork一下修改,但觉得依赖太多,而且我们的项目本身用了Omniauth做登录,用户的token等信息都已经拿到,其实只要用一个http客户端,将auth的信息放在header里面调用相对的api就行了。于是想起了以前用过的gem: [url=https://github.com/technoweenie/faraday]Faraday[/url]

先介绍一下Faraday, 它是一个ruby的http客户端,用类似rack middleware的方式来定制各种http调用。它本身并不实现http客户端,而是用adapter的方式对Net::HTTP, patron甚至 em-http 等提供了封装。非常简单易用,并且容易定制,当然再漂亮的介绍文字都比不过代码,还是上代码,看看它的用途吧。

首先是最基本发布文本到新浪微博,因为weibo接受将token作为一个参数传递,所以就2行代码搞定:

def weibo_update(text)
conn = Faraday.new(:url => 'https://api.weibo.com')
conn.post '/2/statuses/update.json', :access_token => self.token, :status => text
end


然后是发布文本,同时上传一张图片到新浪微博,这个时候需要用到它的Middleware,在定义http connection中设置http request类型为multipart,同时使用Net::HTTP作为adapter(因为默认client的不支持multipart),然后文件使用Faraday::UploadIO,5行代码搞定:

def weibo_upload(text, image_path)
conn = Faraday.new(:url => 'https://api.weibo.com') do |f|
f.request :multipart
f.adapter :net_http
end
conn.post '/2/statuses/upload.json', :access_token => self.token, :status => text, :pic => Faraday::UploadIO.new(image_path, 'image/jpeg')
end


同样的,分享到QQ空间,腾讯微博都只要用类似的方法处理,代码行数也都是2~5行(见文章最后)。
我们再来看看比较复杂的豆瓣 api,豆瓣用的Oauth 1只支持在header里面传递token,并且提交的内容不是key/value那样的form形式,而是xml,代码写成这样:

def douban_saying(content)
conn = Faraday.new(:url => 'http://api.douban.com') do |f|
f.request :oauth, :consumer_key => self.app_id, :consumer_secret => self.app_key, :token => self.token, :token_secret => self.secret
f.request :url_encoded
f.adapter :net_http
end
conn.post do |req|
req.url '/miniblog/saying'
req.headers['Content-Type'] = 'application/atom+xml'
req.body = <<-XML
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/">
<content>#{content}</content>
</entry>
XML
end
end

在request里面我们使用了oauth的middleware(由gem faraday_middleware提供),在header中插入oauth,同时在请求的时候,指定Content-Type,并将body内容设置成xml。但是在使用的时候发现一个问题,豆瓣必须要求header中的Authorization有OAuth realm=xxx的内容,于是我们得自己写一个middleware了,Faraday的middleware和rack很类似,只要实现一个call方法,在这里,我们用正则替换,在已经生成好的Authorization header中替换插入一段realm即可:

class DoubanOauthRealmMiddleware
def initialize(app, options = {})
@app = app
@options = options
end

def call(env)
env[:request_headers]["Authorization"] = env[:request_headers]["Authorization"].gsub(/^OAuth/, "OAuth realm=\"http://api.douban.com\",")
@app.call(env)
end
end


然后将我们写的这个middleware,加入到上面的代码中,就搞定了:

f.request :url_encoded
f.use DoubanOauthRealmMiddleware
f.adapter :net_http


简单的介绍就结束了,其实Faraday还有更多非常棒的功能,比如对于response的自动json解析,自动retry,timeout处理等,都可以通过非常简洁的方式配置和middleware来实现,可以阅读它的源码来了解更多。

附录:发布到QQ空间,腾讯微博的代码,供有用的同学参考:

def qq_add_share(summary, images, title, url)
conn = Faraday.new(:url => 'https://graph.qq.com')
conn.post '/share/add_share', :title => title, :url => url, :summary => summary, :images => images, :source => 1, :type => 4, :nswb => 1,
:access_token => self.token, :openid => self.provider_uid, :oauth_consumer_key => self.app_id
end

def qq_add_t(content)
conn = Faraday.new(:url => 'https://graph.qq.com')
conn.post '/t/add_t', :content => content, :syncflag => 1, :access_token => self.token, :openid => self.provider_uid, :oauth_consumer_key => self.app_id
end

def qq_add_pic_t(content, image_path)
conn = Faraday.new(:url => 'https://graph.qq.com') do |f|
f.request :multipart
f.adapter :net_http
end
conn.post '/t/add_pic_t', :content => content, :pic => Faraday::UploadIO.new(image_path, 'image/jpeg'), :syncflag => 1, :access_token => self.token, :openid => self.provider_uid, :oauth_consumer_key => self.app_id
end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Python模拟登录豆瓣代码实现: ```python import requests from bs4 import BeautifulSoup # 登录页面 login_url = 'https://accounts.douban.com/login' # 请求头 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'} # 获取登录页面的html session = requests.session() response = session.get(login_url, headers=headers) html = response.text # 解析html,获取验证码图片地址和登录需要的captcha-id soup = BeautifulSoup(html, 'html.parser') captcha_url = soup.find('img', {'id': 'captcha_image'}).get('src') captcha_id = soup.find('input', {'name': 'captcha-id'}).get('value') # 下载验证码图片 captcha_response = session.get(captcha_url, headers=headers) with open('captcha.jpg', 'wb') as f: f.write(captcha_response.content) # 输入验证码 captcha_solution = input('请输入验证码:') # 构造登录请求参数 data = { 'source': 'index_nav', 'redir': 'https://www.douban.com/', 'form_email': 'your_email', 'form_password': 'your_password', 'captcha-solution': captcha_solution, 'captcha-id': captcha_id, 'login': '登录' } # 发送登录请求 response = session.post(login_url, data=data, headers=headers) # 验证是否登录成功 if response.url == 'https://www.douban.com/': print('登录成功!') else: print('登录失败!') ``` 以上代码实现了模拟登录豆瓣的功能,具体实现过程如下: 1. 首先发送GET请求获取登录页面的HTML代码。 2. 解析HTML代码,获取验证码图片地址和登录需要的captcha-id。 3. 下载验证码图片,并手动输入验证码。 4. 构造登录请求参数,包括用户名、密码、验证码等信息。 5. 发送POST请求进登录。 6. 验证是否登录成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值