【问题标题】:Android user agent in URLConnectionURLConnection 中的 Android 用户代理
【发布时间】:2016-10-04 14:57:11
【问题描述】:

我试图通过更改连接中的用户代理属性来“愚弄” Google 财经,使其认为我是网络浏览器。但是,当我使用实际的网络浏览器时,我得到的响应仍然不是我应该得到的。我想知道为什么会这样,我需要做什么才能让它工作?以下是相关代码(“站点”为https://www.google.co.uk/finance/converter?a=1&from=GBP&to=USD):

protected static String readURL(String site) {
    StringBuilder buff = new StringBuilder();
    try {
        HttpURLConnection conn = (HttpURLConnection) new URL(site).openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393");
        conn.connect();
        BufferedReader bfr = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        while ((inputLine = bfr.readLine()) != null)
            buff.append(inputLine).append('\n');
        bfr.close();
    }
    catch (Exception ioe) {
        System.err.println("Failed to read from \""+site+"\": "+ioe.getMessage());
    }
    return buff.toString();
}

编辑:我应该注意这是在 Android 应用程序中,而不是在 Java 应用程序中。它也不会在 WebView 或任何东西中向用户显示,这发生在后台。

【问题讨论】:

  • 你返回什么做什么?另外,我不确定您为什么要尝试加载动态表单
  • 它与您的预期有何不同?我的第一个猜测是您所期望的 DOM 的一部分实际上是由 JavaScript 在运行时构建的,而不是 HTML 的一部分,这可能解释了这种差异。
  • 我不能在这里发布完整的 HTML,它太冗长了。但这与 DOM 或 JavaScript 无关。我的问题是我从浏览器返回的内容和程序化查询有很大不同;这只能是因为谷歌知道我没有使用“真正的”网络浏览器。事实上,我知道这一点是因为我以前做过,而且效果很好,但 Google 最近一定更改了他们的网站以检测自动查询。

标签: java android http user-agent urlconnection


【解决方案1】:

网络表单似乎表现正常,没有与用户代理发生冲突。此改造请求返回有效响应:

D/TAG: currency_converter_result>5 GBP = <span class=bld>6.3645 USD

改造请求:

      final Map<String,String> fieldMap = new HashMap<>();

      fieldMap.put("a","5");
      fieldMap.put("from","GBP");
      fieldMap.put("to","USD");

      RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), "");
      final Retrofit retrofit = new Retrofit.Builder()
               .baseUrl("https://www.google.co.uk")
               .build();

         final ConversionService wService = retrofit.create(ConversionService.class);
         Call<ResponseBody> data  = wService.convertCurrency(fieldMap);

         data.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
               String resp = "";

               if ( response.body() != null ) {
                  try {
                     resp = response.body().string();
                     int index = resp.indexOf("currency_converter_result" );
                     int end = resp.indexOf("</span>", index );
                     String result = resp.substring(index, end);
                     Log.d("TAG", result);
                  } catch ( IOException e) {
                  }
               }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

               Log.e(TAG,"Failure");
            }
         });

   }

ConversionService.java

public interface ConversionService {

   @GET("/finance/converter")
   Call<ResponseBody> convertCurrency(@QueryMap Map<String,String> queryMap);
}

【讨论】:

  • 我希望能够在不使用任何其他库的情况下做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
相关资源
最近更新 更多