机械化 google 自动完成
mechanize with google autocomplete
Mechanize 在此页面上找不到表格。所以我试图通过输入填写。问题是表单是 Google 自动完成。首先我需要填写输入,然后 select 从下拉列表中选择一个城市。所以我尝试过的是:
agent = Mechanize.new
page = agent.get("https://www.airbnb.com/host/homes")
location = agent.page.search(".earning-estimation__location-input")
location.at("input")['value'] = 'kiev'
location.at("input")[0].select
并得到:
NoMethodError: private method `select' called for nil:NilClass
P.S。首先,我没有找到 AirBnB API。所以我潜入机械化。如果有爱彼迎 API link 不胜感激。
你的问题并没有真正包含一个问题,所以我对你想要完成的事情的最佳尝试如下:
鉴于我在此页面上看不到太多操作,我假设您希望获得各个区域的每周平均费率。
您实际上不需要根据自动完成填写下拉列表。此交互通过从 Google 地理编码 API 获取 lat/lon 并将其传递给 https://www.airbnb.com/wmpw_data
.
来提供支持
对于需要 javascript 才能运行的网站(像这样),您有两个选择:
- 对他们使用的 API 进行逆向工程(如下例)
- 使用像 Selenium / WebDriver 这样的框架,通过完全原生的浏览器浏览网站。
要对 API 进行逆向工程,Web 调试代理工具非常有用。您可以通过查看浏览器开发工具 "network" 选项卡获得很多信息,但是 "Fiddler"、"Charles Proxy"、"Burp" 等内容非常宝贵。
当您检查流量时,您会看到以下参数可用于在您的请求中发送:
- 第
页
- 持续时间
- person_capacity
- room_type
- 加载中
- sw_lat
- sw_lng
- 新纬度
- ne_lng
您可以使用
之类的东西找到一些有效的值来使用
[37] pry(main)> page.css("[data-room-type]").map{|n| n["data-room-type"]}.uniq
=> ["entire_home_apt", "private_room", "shared_room"]
如果您将各种 lat/lng 值设置为适合您的值,您将获得该地区的每周平均价格。我注意到 "localized_place" 正在报告我的个人区域,而不管 lat/lon 的变化,但货币价值实际上在变化,并且与网站显示的相匹配。也许该属性基于 IP 位置,或者有什么不对劲。
虽然这些值似乎随着 sw/ne 边界的更大和更小区域而缩放,但您也可以对两者使用相同的 lat/lng 并仍然获得结果。它可能无法准确反映 Google Geocoder 引用地点的方式——但它可能足以满足您的使用需求。
一旦你有了获取 lat/lng 的来源,你就可以直接将它们提供给他们的 API。
这似乎是一个有效的例子:
require 'mechanize'
agent = Mechanize.new
page = agent.get "https://www.airbnb.com/host/homes"
room_types = page.css("[data-room-type]").map{|n| n["data-room-type"]}.uniq
# Values for near Charleston, WV, a random place from Google Maps
sw_lat = '38.360928'
sw_lng = '-81.6464767'
ne_lat = sw_lat
ne_lng = sw_lng
duration = '1_week'
person_capacity = 1
room_type = room_types.first # => 'entire_home_apt'
url = "https://www.airbnb.com/wmpw_data?page=slash_host&duration=#{duration}&person_capacity=#{person_capacity}&room_type=#{room_type}&loading=false&sw_lat=#{sw_lat}&sw_lng=#{sw_lng}&ne_lat=#{ne_lat}&ne_lng=#{ne_lng}"
money = agent.get(url).body
require 'json'
JSON.parse(money)["data"]
# => {"average_income_raw"=>385.0,
# "average_income"=>"5",
# "localized_place"=>"xxx",
# "list_your_space_link"=>"https://www.airbnb.com/rooms/new",
# "earning_estimation_duration"=>"1_week",
# "localized_market"=>"Other (International)"}
Mechanize 在此页面上找不到表格。所以我试图通过输入填写。问题是表单是 Google 自动完成。首先我需要填写输入,然后 select 从下拉列表中选择一个城市。所以我尝试过的是:
agent = Mechanize.new
page = agent.get("https://www.airbnb.com/host/homes")
location = agent.page.search(".earning-estimation__location-input")
location.at("input")['value'] = 'kiev'
location.at("input")[0].select
并得到:
NoMethodError: private method `select' called for nil:NilClass
P.S。首先,我没有找到 AirBnB API。所以我潜入机械化。如果有爱彼迎 API link 不胜感激。
你的问题并没有真正包含一个问题,所以我对你想要完成的事情的最佳尝试如下:
鉴于我在此页面上看不到太多操作,我假设您希望获得各个区域的每周平均费率。
您实际上不需要根据自动完成填写下拉列表。此交互通过从 Google 地理编码 API 获取 lat/lon 并将其传递给 https://www.airbnb.com/wmpw_data
.
对于需要 javascript 才能运行的网站(像这样),您有两个选择:
- 对他们使用的 API 进行逆向工程(如下例)
- 使用像 Selenium / WebDriver 这样的框架,通过完全原生的浏览器浏览网站。
要对 API 进行逆向工程,Web 调试代理工具非常有用。您可以通过查看浏览器开发工具 "network" 选项卡获得很多信息,但是 "Fiddler"、"Charles Proxy"、"Burp" 等内容非常宝贵。
当您检查流量时,您会看到以下参数可用于在您的请求中发送:
- 第 页
- 持续时间
- person_capacity
- room_type
- 加载中
- sw_lat
- sw_lng
- 新纬度
- ne_lng
您可以使用
之类的东西找到一些有效的值来使用[37] pry(main)> page.css("[data-room-type]").map{|n| n["data-room-type"]}.uniq
=> ["entire_home_apt", "private_room", "shared_room"]
如果您将各种 lat/lng 值设置为适合您的值,您将获得该地区的每周平均价格。我注意到 "localized_place" 正在报告我的个人区域,而不管 lat/lon 的变化,但货币价值实际上在变化,并且与网站显示的相匹配。也许该属性基于 IP 位置,或者有什么不对劲。
虽然这些值似乎随着 sw/ne 边界的更大和更小区域而缩放,但您也可以对两者使用相同的 lat/lng 并仍然获得结果。它可能无法准确反映 Google Geocoder 引用地点的方式——但它可能足以满足您的使用需求。
一旦你有了获取 lat/lng 的来源,你就可以直接将它们提供给他们的 API。
这似乎是一个有效的例子:
require 'mechanize'
agent = Mechanize.new
page = agent.get "https://www.airbnb.com/host/homes"
room_types = page.css("[data-room-type]").map{|n| n["data-room-type"]}.uniq
# Values for near Charleston, WV, a random place from Google Maps
sw_lat = '38.360928'
sw_lng = '-81.6464767'
ne_lat = sw_lat
ne_lng = sw_lng
duration = '1_week'
person_capacity = 1
room_type = room_types.first # => 'entire_home_apt'
url = "https://www.airbnb.com/wmpw_data?page=slash_host&duration=#{duration}&person_capacity=#{person_capacity}&room_type=#{room_type}&loading=false&sw_lat=#{sw_lat}&sw_lng=#{sw_lng}&ne_lat=#{ne_lat}&ne_lng=#{ne_lng}"
money = agent.get(url).body
require 'json'
JSON.parse(money)["data"]
# => {"average_income_raw"=>385.0,
# "average_income"=>"5",
# "localized_place"=>"xxx",
# "list_your_space_link"=>"https://www.airbnb.com/rooms/new",
# "earning_estimation_duration"=>"1_week",
# "localized_market"=>"Other (International)"}