- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我尝试使用 Ruby 更新我的爱彼迎日历。例如,这是日历的 URL:https://www.airbnb.com/manage-listing/ROOM_ID/calendar
如果您已经在使用 Airbnb,要更新您的日历,您必须依次点击开始日期和结束日期,之后,会弹出一个表单。所以,当我使用 Mechanize 获取页面内容时,这个表单没有加载也没有出现(即使日历是动态加载的,也无法模拟点击),无法使用基本的 Mechanize 表单填写...
我尝试使用 Chrome 的开发者工具来检查网络。当我使用 Chrome 更新日历时,https://www.airbnb.com/api/v2/calendars/ROOM_ID/START_DATE/END_DATE?_format=host_calendar&t=1427377357561&key=d306zoyjsyarp7ifhu67rjxn52tv0t20
有一个 JSON PUT带有一些 JSON 数据,例如天数、可用性、价格...
我的第一个解决方案是尝试使用以下代码重现此 JSON 调用:
data = { "event_name" => "calendar",
"event_data" => { "page_uri" => "/manage-listing/ROOM_ID/calendar",
"controller" => "rooms",
"action" => "manage_listing",
"hosting_id" => ROOM_ID,
"start_date" => "2015-03-26",
"end_date" => "2015-03-29",
"available" => true,
"native_price" => 111,
"native_currency" => "EUR"
}
}
page = agent.post 'https://www.airbnb.com/api/v2/calendars/ROOM_ID/2015-03-26/2015-03-29?_format=host_calendar&t=1427374574309&key=d306zoyjsyarp7ifhu67rjxn52tv0t20', data.to_json, {'Content-Type' => 'application/json'}
但我收到 404 响应:
Mechanize::ResponseCodeError (404 => Net::HTTPNotFound for https://www.airbnb.com/api/v2/calendars/ROOM_ID/2015-03-26/2015-03-29?_format=host_calendar&t=1427374574309&key=d306zoyjsyarp7ifhu67rjxn52tv0t20 -- unhandled response)
您有什么建议是发送表单(即使它不在页面内容中),还是使用 JSON POST 请求?
谢谢你的帮助
这是来自 Chrome 的完整 JSON 调用:
一般
Remote Address:xx.xx.xx.xx:xx
Request URL:https://www.airbnb.com/api/v2/calendars/ROOM_ID/2015-03-26/2015-03-29?_format=host_calendar&t=1427379998507&key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=EUR&locale=fr-CA
Request Method:PUT
Status Code:200 OK
响应 header
cache-control:max-age=0, private, must-revalidate
connection:keep-alive
content-encoding:gzip
content-length:236
content-type:application/json; charset=utf-8
date:Thu, 26 Mar 2015 14:26:46 GMT
etag:W/"10845765865e36a6ccb1541bbda1c2a7"
server:nginx/1.7.7
status:200 OK
status:200 OK
strict-transport-security:max-age=10886400; includeSubdomains
vary:Accept-Encoding
version:HTTP/1.1
x-frame-options:SAMEORIGIN
x-hi-human:The Production Infrastructure team added this header. Come work with us! Email kevin.rice+hiring@airbnb.com
x-ua-compatible:IE=Edge,chrome=1
x-xss-protection:1; mode=block
请求 header
:host:www.airbnb.com
:method:PUT
:path:/api/v2/calendars/ROOM_ID/2015-03-26/2015-03-29?_format=host_calendar&t=1427379998507&key=d306zoyjsyarp7ifhu67rjxn52tv0t20¤cy=EUR&locale=fr-CA
:scheme:https
:version:HTTP/1.1
accept:application/json, text/javascript, */*; q=0.01
accept-encoding:gzip, deflate, sdch
accept-language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
content-length:59
content-type:application/json
cookie:__ssid=4166c81a-49bd-4826-ac44-08307c5700ca; _csrf_token=V4%24.airbnb.ca%24CL1nNdfYkF0%24ulPyJJJWr1h6CvuBMf32YcXtnZssDud3_CqBQoqXOU0%3D; li=1; roles=0; _airbed_session_id=dfa72c17e6d014f9fd0b9705d097e5d8; flags=4027711488; EPISODES=s=1427377914349&r=https%3A%2F%2Ffr.airbnb.ca%2Fmanage-listing%2F5780104%2Fcalendar; _ga=GA1.2.1981489078.1427272843; fbs=not_authorized; _pt=1--WyJjZmYxZmE4N2RhOTU4NGNhYzhhN2M5YTIyNzkyMDliMDI0YTk1YWEzIl0%3D--2890e7d8df5181677516659fbdc4761e6de82a61; bev=1427272835_bw8KI59ELTQAsMt3; _user_attributes=%7B%22curr%22%3A%22EUR%22%2C%22guest_exchange%22%3A0.9134%2C%22id%22%3A29905162%2C%22hash_user_id%22%3A%22cff1fa87da9584cac8a7c9a2279209b024a95aa3%22%2C%22eid%22%3A%22FBPqvskr4MN1Rnpqf-oY-lG7-VNdCJVSYwUMUtm6YyOXzEpbRvmU9FWTxKNdf0UA%22%2C%22num_msg%22%3A0%2C%22num_h%22%3A1%2C%22name%22%3A%22St%C3%A9phane%22%2C%22is_admin%22%3Afalse%2C%22can_access_photography%22%3Afalse%7D
origin:https://www.airbnb.com
referer:https://www.airbnb.com/manage-listing/ROOM_ID/calendar
user-agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
x-csrf-token:V4$.airbnb.ca$CL1nNdfYkF0$ulPyJJJWr1h6CvuBMf32YcXtnZssDud3_CqBQoqXOU0=
x-requested-with:XMLHttpRequest
查询字符串参数
_format:host_calendar
t:1427379998507
key:d306zoyjsyarp7ifhu67rjxn52tv0t20
currency:EUR
locale:fr-CA
请求负载
{availability: "available", daily_price: "999", notes: ""}
availability: "available"
daily_price: "999"
notes: ""
最佳答案
我使用 JSON PUT 请求成功更新了房间的日历。这是我所做的。
数据看起来像:
data = { "availability" => availability,
"daily_price" => price,
"notes" => note
}.to_json
检索 cookie:
cookie_csrf_token = ''
cookie_airbed_session_id = ''
agent.cookie_jar.each do |value|
if value.to_s.include? "_csrf_token"
cookie_csrf_token = value.to_s
elsif value.to_s.include? "_airbed_session_id"
cookie_airbed_session_id = value.to_s
end
end
标题:
headers = { 'X-CSRF-Token' => URI.unescape(cookie_csrf_token.scan(/=(.*)/).join(",")),
'Content-Type' => 'application/json',
'Cookie' => "#{cookie_csrf_token}; #{cookie_airbed_session_id}"
}
您唯一需要的 cookie 是相互关联的 csrf_token 和 airbed_session_id。我的错误是使用了登录页面中的 csrf_token...您可以在 Mechanize 代理的 cookie_jar 变量中找到这些 cookie。
之后您将需要构建您的 URL。 URL 有一个称为“键”的特定参数。您可以在日历页面的元标记 (id='_bootstrap-layout-init'
) 中检索它。为此,我将 Nokogiri 与一些正则表达式结合使用:
param_t = Time.now.to_i
noko.xpath("//meta[@id='_bootstrap-layout-init']/@content").each do |attr|
param_key = attr.value[/key":"(.*?)"/, 1]
end
现在您可以开始更新您的日历了:
url = "https://www.airbnb.com"
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# Send the PUT request to update the calendar
res = http.start { |req|
req.send_request('PUT', "/api/v2/calendars/#{room_id}/#{start_date}/#{end_date}?_format=host_calendar&t=#{param_t}&key=#{param_key}", data, headers)
}
关于Ruby Mechanize,填充动态表单/发送 JSON(Airbnb 日历),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29280964/
我在 mongodb 中的玩家和锦标赛之间存在多对多关系。 我希望能够一次将许多玩家添加到锦标赛中。如果没有 ajax,这很简单,但我们有一个包含数千名玩家的数据库,因此表单选择变得巨大。 我们想为此
这个问题已经有答案了: When should I use html's and when spring's in Spring MVC web app? (3 个回答) 已关闭 6 年前。 我正
我正在 C++ Builder XE4 上使用 VCL。 我有以下组件。 FormMain 具有 TButton *B_select; FormSelect(或DialogSelect)具有 TCom
如何在不影响表单控件的情况下更改表单的 alphablend? 德尔福XE7 最佳答案 此问题的一个解决方案是使用多设备应用程序(如果无法使用VCL)。 如果您需要保留透明的TForm,只需更改属性T
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我正在尝试扩展 Django 注册以包含我自己的注册表单。原则上这是相当简单的。我只需要编写自己的表单( CustomRegistrationForm ),它是原始表单( RegistrationFo
我正在尝试为我的网站实现聊天功能。为了做到这一点,我遵循了以下教程:https://channels.readthedocs.io/en/latest/tutorial/ 然后我稍微更改了代码以实现它
有一个问题,我需要用一个 html 表单提交两个相互关联的模型表单。我知道如何提交两个单独的表格,但是在相关模型表格的情况下外键让我发疯。 问题是,第二个表单应该用外键填充字段到第一个表单的实例。 在
我正在创建一个工具,允许某人输入食谱,然后将其保存为 XML 文件,我已经创建了 XSD,但我想知道如何在我的网页上制作一个表单以允许用户输入他们的食谱并遵守模式。我一直在研究 Ajax 和 Jque
在 .net win 表单(如 asp.net web 表单)中是否有可用的验证控件? 因为很难为我的每个控件设置正确的条件,所以我的表单中也有很多重复的代码。 正确的做法是什么? 最佳答案 看看这个
我有一个简短的问题。我正在学习如何使用 javascript 制作注册表,发现此链接非常有用。 http://www.w3resource.com/javascript/form/javascript
我正在开发一个项目,该项目将使用循环将许多表单添加到 mysql 数据库中。在 javascript 部分中,我无法让 var i 在函数 updatesum() 中工作。有人可以帮我吗? 我试图避免
在我的应用程序上有一个包含 2 个字段和一个保存按钮的表单。 在我的 onClick 结束时我需要什么来将光标返回到第一个字段。 我有这个来清除它们 txtData.setText("
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
<input type="text" name="textfield" onKeyPress="javascript:alert(event.
我正在构建的网站有一个登录表单,作为所有其他模板扩展的 base.html 模板的一部分;因此,我需要以某种方式处理每个页面上的登录/注销逻辑。 目前每个页面都在单独的 View 中加载,那么实现它的
我有一个表单类,看起来像.. #forms.py class ExampleForm(forms.Form): color = forms.CharField(max_length=25)
有没有办法在表单定义中给表单一个特殊的错误渲染函数?在 customizing-the-error-list-format 下的文档中它展示了如何为表单提供特殊的错误呈现函数,但似乎您必须在实例化表单
我正在处理由多个页面组成的表单,我想解决验证问题。 当我点击提交按钮时,当前页面上的所有字段都会在下方显示错误消息,但是如果我更改页面,那么我需要再次点击提交,因为这些字段未设置为已触摸。 如果我可以
是否可以附加到继承表单的 exclude 或 widgets 变量? 到目前为止,我有以下设置。 class AddPropertyForm(forms.ModelForm): num_mon
我是一名优秀的程序员,十分优秀!