关于苹果什么时候出新电脑电脑看到信息时2015年的信息是不是知乎

业精于勤,荒于嬉;行成于思,毁于随!
Android(Java) 模拟登录知乎并抓取用户信息
前不久,看到一篇文章,该文章中使用的登录方式是直接复制cookie到代码中,这里呢,我不以爬信息为目的。只是简单的介绍使用java来进行模拟登录的基本过程,之前写过的文章其实就是模拟登录的范畴。再加上最近在知乎上看到很多人问关于超级课程表的实现,其实本质就是模拟登录,掌握了这篇文章的内容,你不再担心抓不到信息了。然后,这篇文章会使用到之前的一篇Cookie保持的文章,还有Jsoup的使用,为了简单处理,直接使用javaSE来,而不再使用Android进行。如果要移植到Android,唯一的处理可能就是把网络请求工作扔到子线程中去
首先使用Chrome打开
, 点击登录,你会看到下面这个界面
在Chorme中按F12,调出开发者工具,切到Network选项卡,勾选Preserve Log,记得一定要勾选,不然你会看不到信息。
一切就绪后,在输入框中输出账号密码点击登录,登录成功后你会看到这么一条记录
点击图中的email,在最下方你会看到本次请求提交了4个参数,以及在上方,你会看到本次请求的地址是
你会惊讶的发现知乎的密码是明文传输的,提交的参数的意思也很简单,email就是账号,password就是密码,remember_me就是是否记住,这里传true就可以了,还有一个_xsrf参数,这个毛估估应该是防爬虫的。因此在提交前我们要从源代码中将这个值抓取下来。该值在表单的隐藏域中
一切准备就绪后,你就兴高采烈的用代码去模拟登录,然后你会发现会返回一个验证码错误的信息。其实,我们还需要提交一个验证码,其参数名为captcha,验证码的地址为,
http://www.zhihu.com/captcha.gif?r=时间戳
于是我们得出了这样的一个数据。
http://www.zhihu.com/login/email
_xsrf 表单中提取的隐藏域的值
captcha 验证码
email 邮箱
password 密码
还有一个问题,验证码的值怎么得到呢,答案是人工输入,将验证码保存到本地进行认为识别,输入后进行登陆即可。
这里的网络请求使用OkHttp,以及解析使用Jsoup,然后我们会使用到Gson,将他们加入maven依赖
<pre class="prettyprint prettyprinted" data-original-code="
com.squareup.okhttp
com.google.code.gson
" data-snippet-id="ext.954a1d7d6c4276c4faf0df" data-snippet-saved="false" data-csrftoken="20AinXcm-dRsprSXazhrt6nBpMoaeJ3OOLFA" data-codota-status="done">
&com.squareup.okhttp&
&org.jsoup&
&com.google.code.gson&
在编码之前,我们得想想怎么维持登陆状态,没错,就是Cookie如何保持,我们只进行登陆一次,后续都直接采集数据就可以了,因此需要将cookie持久化,对之前的文章中的一个Android类进行改造。使其变成java平台可用的类,可以看到我们将它从之前保存到SharePrefrences中改成了保存到文件中,并以json形式存储,这就是为什么会用到Gson的原因了
package cn.edu.zafu.
import com.google.gson.G
import com.google.gson.GsonB
import com.google.gson.reflect.TypeT
import java.io.*;
import java.net.CookieS
import java.net.HttpC
import java.net.URI;
import java.net.URISyntaxE
import java.util.*;
import java.util.concurrent.ConcurrentHashM
* User:lizhangqu()
* Time: 16:54
public class PersistentCookieStore implements CookieStore {
private static final Gson gson= new GsonBuilder().setPrettyPrinting().create();
private static final String LOG_TAG = "PersistentCookieStore";
private static final String COOKIE_PREFS = "CookiePrefsFile";
private static final String COOKIE_NAME_PREFIX = "cookie_";
private final HashMap&String, ConcurrentHashMap&String, HttpCookie&&
Map&String,String& cookiePrefs=new HashMap&String, String&();
* Construct a persistent cookie store.
public PersistentCookieStore() {
String cookieJson = readFile("cookie.json");
Map&String,String& fromJson = gson.fromJson(cookieJson,new TypeToken&Map&String, String&&() {}.getType());
if(fromJson!=null){
System.out.println(fromJson);
cookiePrefs=fromJ
cookies = new HashMap&String, ConcurrentHashMap&String, HttpCookie&&();
for(Map.Entry&String, ?& entry : cookiePrefs.entrySet()) {
if (((String)entry.getValue()) != null && !((String)entry.getValue()).startsWith(COOKIE_NAME_PREFIX)) {
String[] cookieNames = split((String) entry.getValue(), ",");
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.get(COOKIE_NAME_PREFIX + name);
if (encodedCookie != null) {
HttpCookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if(!cookies.containsKey(entry.getKey()))
cookies.put(entry.getKey(), new ConcurrentHashMap&String, HttpCookie&());
cookies.get(entry.getKey()).put(name, decodedCookie);
public void add(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
if (!cookie.hasExpired()) {
if(!cookies.containsKey(uri.getHost()))
cookies.put(uri.getHost(), new ConcurrentHashMap&String, HttpCookie&());
cookies.get(uri.getHost()).put(name, cookie);
if(cookies.containsKey(uri.toString()))
cookies.get(uri.getHost()).remove(name);
cookiePrefs.put(uri.getHost(), join(",", cookies.get(uri.getHost()).keySet()));
cookiePrefs.put(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableHttpCookie(cookie)));
String json=gson.toJson(cookiePrefs);
saveFile(json.getBytes(), "cookie.json");
protected String getCookieToken(URI uri, HttpCookie cookie) {
return cookie.getName() + cookie.getDomain();
public List&HttpCookie& get(URI uri) {
ArrayList&HttpCookie& ret = new ArrayList&HttpCookie&();
if(cookies.containsKey(uri.getHost()))
ret.addAll(cookies.get(uri.getHost()).values());
public boolean removeAll() {
cookiePrefs.clear();
cookies.clear();
return true;
public boolean remove(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
if(cookies.containsKey(uri.getHost()) && cookies.get(uri.getHost()).containsKey(name)) {
cookies.get(uri.getHost()).remove(name);
if(cookiePrefs.containsKey(COOKIE_NAME_PREFIX + name)) {
cookiePrefs.remove(COOKIE_NAME_PREFIX + name);
cookiePrefs.put(uri.getHost(), join(",", cookies.get(uri.getHost()).keySet()));
return true;
return false;
public List&HttpCookie& getCookies() {
ArrayList&HttpCookie& ret = new ArrayList&HttpCookie&();
for (String key : cookies.keySet())
ret.addAll(cookies.get(key).values());
public List&URI& getURIs() {
ArrayList&URI& ret = new ArrayList&URI&();
for (String key : cookies.keySet())
ret.add(new URI(key));
} catch (URISyntaxException e) {
e.printStackTrace();
* Serializes Cookie object into String
* cookie cookie to be encoded, can be null
* cookie encoded as String
protected String encodeCookie(SerializableHttpCookie cookie) {
if (cookie == null)
return null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
System.out.println("IOException in encodeCookie"+ e);
return null;
return byteArrayToHexString(os.toByteArray());
* Returns cookie decoded from cookie string
* cookieString string of cookie as returned from http request
* decoded cookie or null if exception occured
protected HttpCookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
HttpCookie cookie = null;
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).getCookie();
} catch (IOException e) {
System.out.println("IOException in decodeCookie"+e);
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException in decodeCookie"+e);
* Using some super basic byte array &-& hex conversions so we don't have to rely on any
* large Base64 libraries. Can be overridden if you like!
* bytes byte array to be converted
* string containing hex values
protected String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte element : bytes) {
int v = element & 0xff;
if (v & 16) {
sb.append('0');
sb.append(Integer.toHexString(v));
return sb.toString().toUpperCase(Locale.US);
* Converts hex values from strings to byte arra
* hexString string of hex-encoded values
* decoded byte array
protected byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i & i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) && 4) + Character.digit(hexString.charAt(i + 1), 16));
public static String join(CharSequence delimiter, Iterable tokens) {
StringBuilder sb = new StringBuilder();
boolean firstTime = true;
for (Object token: tokens) {
if (firstTime) {
firstTime = false;
sb.append(delimiter);
sb.append(token);
return sb.toString();
public static String[] split(String text, String expression) {
if (text.length() == 0) {
return new String[]{};
return text.split(expression, -1);
public static void saveFile(byte[] bfile, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
file = new File(fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
if (fos != null) {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
public static String readFile(String fileName) {
BufferedInputStream bis = null;
FileInputStream fis = null;
File file = null;
file = new File(fileName);
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
int available = bis.available();
byte[] bytes=new byte[available];
bis.read(bytes);
String str=new String(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
} catch (IOException e1) {
e1.printStackTrace();
if (fis != null) {
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
return "";
然后新建一个OkHttp请求类,并设置其Cookie处理类为我们编写的类。
private static OkHttpClient client = new OkHttpClient();
client.setCookieHandler(new CookieManager(new PersistentCookieStore(), CookiePolicy.ACCEPT_ALL));
好了,可以开始获取_xsrf以及验证码了。验证码保存在项目根目录下名为code.png的文件
然后将获取来的参数连同账号密码进行提交登录
当看到下面的信息就代码登录成功了
之后你就可以获取你想要的信息了,这里简单获取一些信息,比如我要获取轮子哥的followers的昵称,分页自己处理下就ok了。
public static void getFollowers() throws IOException{
Request request = new Request.Builder()
.url("http://www.zhihu.com/people/zord-vczh/followees")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0. Safari/537.36")
Response response = client.newCall(request).execute();
String result=response.body().string();
Document parse = Jsoup.parse(result);
Elements select = parse.select("div.zm-profile-card");
StringBuilder builder=new StringBuilder();
for (int i=0;i&select.size();i++){
Element element = select.get(i);
String name=element.select("h2").text();
System.out.println(name+"");
builder.append(name);
builder.append("\n");
下图就是获取到的信息。当然,只要你登录了,什么信息你都可以获取到。
最后上源码,Intelij的maven项目
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!工作中能力很强的人平时有哪些共同的特征? - 知乎_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
工作中能力很强的人平时有哪些共同的特征? - 知乎
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
&#xe64e;加入VIP
还剩16页未读,
定制HR最喜欢的简历
你可能喜欢ProcessOn - 免费在线作图,实时协作
免费在线作图,实时协作
ProcessOn 支持流程图、思维导图、原型图、UML、网络拓扑图等
高效易用、轻松绘制
ProcessOn是一个在线作图工具的聚合平台,它可以在线画流程图、思维导图、UI原型图、UML、网络拓扑图、组织结构图等等,您无需担心下载和更新的问题,不管Mac还是Windows,一个浏览器就可以随时随地的发挥创意,规划工作
团队协作、头脑风暴
您可以把作品分享给团队成员或好友,无论何时何地大家都可以对作品进行编辑、阅读和评论
海量图库,知识分享
ProcessOn不仅仅汇聚着强大的作图工具,这里还有着海量的图形化知识资源我们尽可能的将有价值的知识进行梳理,传递到您的眼前
关注微信公众号中国马拉松
近期报名赛事
2017特步·中国马拉松年度盛典召开
首届中国马拉松摄影大赛收官
第二届中国马拉松博览会落幕
2018建发·厦门马拉松鸣枪开赛
参赛成绩查询
马拉松视频
国内跑者排名
1.杨定宏02:13:372017
2.李子成02:15:212017
3.关思杨02:17:572017
4.管油胜02:19:532017
5.邱旺东02:20:542017
6.狄鋆02:22:022017
7.贾俄仁加02:22:272017
8.李鹏02:24:212017
9.运艳桥02:24:362017
10.碾者阿提02:24:592017
1.何引丽02:30:262017
2.郑芝玲02:33:502017
3.李芷萱02:35:422017
4.李丹02:35:482017
5.李文杰02:39:392017
6.焦安静02:40:172017
7.郝晓帆02:44:002017
8.王悦02:44:322017
9.苏雪婷 02:45:292017
10.王敏02:46:412017
1.李子成01:04:282017
2.刘洪亮01:04:402017
3.彭建华01:05:012017
4.杨乐01:05:392017
5.杨定宏01:05:412017
6.林鑫01:06:112017
7.曹少波01:06:232017
8.关思杨01:06:392017
9.许安雷01:06:572017
10.边岐01:07:102017
1.张莹莹01:12:232017
2.王雪芹01:13:132017
3.赵艳丽01:14:422017
4.刘壮01:15:182017
5.魏小杰01:15:182017
6.郝晓帆01:15:292017
7.马玉贵01:15:362017
8.何引丽01:15:532017
9.刘梦01:16:112017
10.焦安静01:16:192017
1.丛巍巍00:31:392017
2.关思杨00:31:512017
3.吴向东00:32:002017
4.董瑞皇00:32:122017
5.曹少波00:32:162017
6.骆淳00:32:192017
7.沙宇超00:32:262017
8.李星00:32:262017
9.聂登宇00:32:272017
10.杜士洋00:32:332017
1.罗川00:34:522017
2.李美珍00:35:162017
3.夏雨雨00:36:022017
4.陈林明00:36:122017
5.何巫呷00:36:172017
6.牛丽华00:36:562017
7.王悦00:37:032017
8.林霞00:37:102017
9.周婷婷00:37:232017
10.殷晓雨00:37:302017在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
大都数网站(如segmentfault、知乎)的消息功能是采用什么样技术和原理实现的? (如我的文章被评论、被关注,就会收到系统推送的相关消息)。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
一种是循环轮询,一种是websocket前一种兼容性比较好,可以到IE6
后一种性能比较好
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
在此页面按 F12,打开调试面板,点击 Network,静静的等。。。。
在我写这个答案的时候,等候的结果
随便点开一个看看
http://segmentfault.com/api/user/stat?types%5B%5D=events&_=f367c84ccf38a04e19ffb
sf 使用了一个 ajax 轮询,周期性的向服务器发送 GET 请求,types%5B%5D=events 就是 types[]=events,后面的参数是 csrf token 吧
我们再看看相应
题主可以一直开着,当别人回答了你的问题,或者赞了你,你就可以收到消息了。
你说“会收到系统推送的相关消息”,其实,不是服务器推送,而是客户端拉取的。
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。

我要回帖

更多关于 苹果电脑查询激活时间 的文章

 

随机推荐