我正试图使用Ruby和HTTParty在Wikia上的论坛上发帖。没有可用的文档,因为这个过程似乎涉及Wikia的内部API,所以我一直在尝试使用Chrome的开发工具来查看请求。
据我所知,当用户试图在论坛上的帖子中发表评论时,会向.wikia.com/wikia.php发送post请求,其中包含以下参数:
- controller=墙外部
- method=replyToMessage
- parent=(父线程id,例如1036301)
- body="正在发送的消息"
- token=编辑令牌*
该过程需要一个编辑令牌,我使用普通的Mediawiki API检索该令牌。我遇到的问题是我得到了
的响应
"您的登录会话似乎有问题;为了防止会话劫持,此操作已被取消。请返回上一页,重新加载该页,然后重试。"
使用错误消息的谷歌搜索只会让出现这种情况的人在尝试正常登录时出现,这在这种情况下不是问题。
我认为问题可能在于请求中没有设置用户的头部,因为我认为匿名编辑不允许发布响应;由于Mediawiki文档说没有登录的用户会得到一个"+\"的编辑令牌,所以事实似乎并非如此。
我尝试使用的代码是:
@api = MediaWiki::Gateway.new 'http://example.wikia.com/api.php'
@api.login('username', 'password')
@headers = {
'User-Agent' => 'example',
'Cookie' => @api.cookies.map { |k, v| "#{k}=#{v};" }.join(' ')
}
query = HTTParty.post('http://example.wikia.com/api.php',
:body => {
'action' => 'query',
'prop' => 'info|revisions',
'intoken' => 'edit',
'titles' => 'Thread:2219',
'format' => 'json'
},
:headers => @headers
)
token = JSON.parse(query.body)
token = token["query"]["pages"]["-1"]["edittoken"]
query = HTTParty.post('http://example.wikia.com/wikia.php',
:body => {
'controller' => 'WallExternal',
'method' => 'changeThreadStatus',
'format' => 'json',
'msgid' => '2219',
'newState' => 'close'
},
:headers => @headers
)
Wikia目前正在使用Mediawiki1.19.24,这就是为什么检索编辑令牌的方法是旧版本的原因。
这主要是一种爱好,我经验不多。我先在维基论坛上问过这个问题,一位用户建议我来这里。感谢您提供的任何帮助。
您看到一个与CSRF(跨站点请求伪造)有关的错误,因为您无法正确使用"令牌"。
这可能是MediaWiki网站创建者有意为之。除非传递正确的令牌,否则您将无法进行POST,该令牌表明表单是从正确的HTML页面来源提交的。此令牌源自服务器,您可能很难提取它以用于HTTParty请求。不过,您可以在DOM中查找一些值。
我可能建议使用硒作为替代品。由于这使用了一个合适的浏览器实例,您不必处理解析HTML响应和制作自定义帖子的问题。相反,您可以编写代码访问Wiki网站,登录并提交"新帖子"表单。
请记住,有时网站有保护措施,以避免以这种方式实现自动化。如果您发现发生这种情况(例如,您无法使用Selenium登录),在Selenium代码中放置断点,在浏览器中单击,然后越过断点运行更多代码会很有帮助。
尽管如此,由于存在MediaWiki API,因此尽可能多地使用该接口可能是一个更好的想法。也就是说,如果gem可以满足您的需求,那么可能不需要使用HTTP客户端或无头浏览器。