是否可以在2015年使用Http Client登录Facebook登录?

时间:2015-09-15 08:23:41

标签: facebook login httpclient

这些年来有几个类似的问题,但即使是那些发布的问题也与我要问的内容并不完全相关。其余的没有答案或促进使用已弃用的代码和方法。所以我不认为我的问题是重复的。

我正在尝试使用Apache HttpClient使用我的个人FB凭据登录以获得完整的搜索选项,这些选项不属于Graph API(例如通过电子邮件搜索等)。所以我几乎都在问这是否可行?似乎有可能在当时。

我在代码中尝试了很多东西,所以我只会粘贴我正在做的简短版本。问题是我总是收到一条错误消息,指出Cookies是必需的并且未启用。

我正在使用Apache httpclient 4.4.1。请不要粘贴一些您未测试过的代码。欢迎提出想法。我首先向登录页面发出GET请求以检索cookie,但是没有cookie存储在CookieStore中,无论我设置什么cookie策略,或者即使我添加了相同的http上下文两个请求:

CookieStore getCookieStore = new BasicCookieStore();
RequestConfig globalConfig = RequestConfig.custom()
            .setCookieSpec(CookieSpecs.DEFAULT)
            .build();
HttpClient getHttpClient = HttpClientBuilder
            .create()
            .setDefaultRequestConfig(globalConfig)
            .setDefaultCookieStore(getCookieStore)
            .build();
BasicHttpContext httpContext = new BasicHttpContext();
    httpContext.setAttribute(ClientContext.COOKIE_STORE, getCookieStore);

HttpGet getPageRequest = new HttpGet(FACEBOOK_LOGIN_URL);
getPageRequest.setHeader("User-Agent", "Mozilla/5.0");
getPageRequest.setHeader("Host", FACEBOOK_DOMAIN_URL);
getPageRequest.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,**/ *//*;q=0.8");
getPageRequest.setHeader("Accept-Language", "en-US,en;q=0.5");
getPageRequest.setHeader("Connection", "keep-alive");
getPageRequest.setHeader("Referer", FACEBOOK_LOGIN_URL);
getPageRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");

getHttpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

// NO COOKIES HERE !!!
CookieStore postCookieStore = new BasicCookieStore();
    System.out.println("getCookieStore.getCookies().size(): " +   getCookieStore.getCookies().size());
getCookieStore.getCookies().forEach(postCookieStore::addCookie);

HttpClient postHttpClient = HttpClientBuilder
            .create()
            .setDefaultRequestConfig(globalConfig)
            .setDefaultCookieStore(postCookieStore)
            .build();

HttpPost loginRequest = new HttpPost(FACEBOOK_LOGIN_URL);
List<NameValuePair> loginCredentials = new ArrayList<>();

Document loginPageDocument = Jsoup.parse(getPageEntityString);
Elements hiddenInputElements = loginPageDocument.select("input[type=hidden]");
for (Element element : hiddenInputElements) {
    String id = element.id();
    String value = element.val();
    loginCredentials.add(new BasicNameValuePair(id, value));
}

loginCredentials.add(new BasicNameValuePair("email", EMAIL));
loginCredentials.add(new BasicNameValuePair("pass", PASS));

loginRequest.setEntity(new UrlEncodedFormEntity(loginCredentials));

loginRequest.setHeader("User-Agent", "Mozilla/5.0");
loginRequest.setHeader("Host", FACEBOOK_DOMAIN_URL);
loginRequest.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
loginRequest.setHeader("Accept-Language", "en-US,en;q=0.5");
loginRequest.setHeader("Connection", "keep-alive");
loginRequest.setHeader("Referer", FACEBOOK_LOGIN_URL);
loginRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");

String loginEntityString = "";
try {
    HttpResponse loginResponse = postHttpClient.execute(loginRequest);
    HttpEntity loginEntity = loginResponse.getEntity();
    loginEntityString = EntityUtils.toString(loginEntity);
    EntityUtils.consume(loginEntity);
} catch (Throwable t) {
    System.err.println(t.getMessage());
} finally {
    loginRequest.releaseConnection();
}

System.out.println(loginEntityString);

1 个答案:

答案 0 :(得分:1)

我发现以编程方式登录Facebook的唯一可能方式是使用Selenium,这可能不是每个应用程序的最佳方式,但它会为我工作。这是登录Facebook并搜索关键短语的工作示例。如果网站的HTML发生变化,它可能在不久的将来无效。

    WebDriver driver = new FirefoxDriver();
    driver.navigate().to("https://www.facebook.com/");

    driver.findElement(By.id("email")).sendKeys(YOUR_FACEBOOK_EMAIL);
    WebElement passInput = driver.findElement(By.id("pass"));
    passInput.sendKeys(YOUR_FACEBOOK_PASS);
    passInput.sendKeys(Keys.ENTER);

    WebElement searchInput = driver.findElement(By.cssSelector("[aria-label='Search Facebook']"));
    searchInput.sendKeys("YOUR_SEARCH_PHRASE");

    WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(presenceOfElementLocated(By.cssSelector("[aria-label='Search']")));

    WebElement searchButton = driver.findElement(By.cssSelector("[aria-label='Search']"));
    searchButton.click();