2 模拟登录_Post表单方式(针对chinaunix有效,针对csdn失效,并说明原因)
参考精通Python网络爬虫实战
首先,针对chinaunix
import urllib.request
#原书作者提供的测试url
url="http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LctlC"
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400")
postdata=urllib.parse.urlencode({
"username":"xiaojieshisilang",
"password":"XXXXX"
}).encode('utf-8')
req=urllib.request.Request(url,postdata)
req.add_header(headers[0],headers[1])
data=urllib.request.urlopen(req).read()
#print (data)
fhandle=open("./8.html","wb")
fhandle.write(data)
fhandle.close() #设置要爬去的该网站下其他网页的网址
url2="http://bbs.chinaunix.net/forum.php?mod=guide&view=my"#这是从网页登录以后,才能进入的个人空间。
req2=urllib.request.Request(url2,postdata)
req2.add_header(headers[0],headers[1])
data2=urllib.request.urlopen(req2).read()
#print (data2)
fhandle=open("./8_2.html","wb")
fhandle.write(data2)
fhandle.close()
上面的password需要你自己去注册。
关键点在于获取用于针对post用户名和密码信息之后的那个URL,以及构建PostData表单字典。
第一,如何获取URL呢?
F12打开调试界面。
输入错误的用户名add和密码add,可以看到URL信息如下:

以及FormData信息如下:

同时,我们就能构造出
postdata=urllib.parse.urlencode({
"username":"xiaojieshisilang",
"password":"XXXXXXXXXXX"
}).encode('utf-8')
这里要填入正确的用户名和密码。
最后代码的运行结果是:打开8_html

同时,8-2.html则是:

关于构建postData时的名称,除了用F12调试的方式。
另外一种是,直接放在文本框,用右键检查的方式,从而定位到相应的源码,取出表单的名称,比如:username和password。

下面针对CSDN进行类似操作

输入错误的用户名和密码

这个时候,查看Form Data,即表单数据。

import urllib.request
url="https://passport.csdn.net/account/verify"
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400")
postdata=urllib.parse.urlencode({
"username":"183247166@qq.com",
"password":"XXXXXX"
}).encode('utf-8')
req=urllib.request.Request(url,postdata)
req.add_header(headers[0],headers[1])
data=urllib.request.urlopen(req).read()
#print (data)
fhandle=open("./8.html","wb")
fhandle.write(data)
fhandle.close() #设置要爬去的该网站下其他网页的网址
url2="https://download.csdn.net/my"#这是从网页登录以后,才能进入的个人空间。
req2=urllib.request.Request(url2,postdata)
req2.add_header(headers[0],headers[1])
data2=urllib.request.urlopen(req2).read()
#print (data2)
fhandle=open("./8_2.html","wb")
fhandle.write(data2)
fhandle.close()
结果是:


不能正确登录csdn,并且爬虫。
这说明,csdn的验证机制,不是简单的一个post就能完成的。
失败原因分析
https://blog.csdn.net/yanggd1987/article/details/52127436
这个链接是前人的博客。大家同时可以参考Python3网络爬虫开发实战一书中的观点,要先获取隐藏表单中的值,然后再构造post数据,用python模拟登录。
但是,最新版本,截止到当前时间2018年7月13日09:54:03时,csdn的验证机制变了。具体如下:
用F12进行调试时,追踪post请求数据,可以看到,相比于以前各个博文中的多了一个fkid值。
之前的:
values = {
"username":"用户名",
"password":"密码",
"lt":lt,
"execution":execution,
"_eventId":"submit"
}
现在的:

尝试抓取隐藏表单数据。我们F12调试的时候,选择Preseve log选项,选择chrome浏览器。
刷新csdn的登录界面,可以看到开发者模式记录的第一个请求实Get请求,访问的是https://passport.csdn.net/account/login,类似于github的机制,这个时候,访问这个页面,会忘隐藏表单中填入相关的数据。具体请求的信息如下:

服务器会Response一些set_cookie的信息,要求浏览器客户端设置cookie文件。
这些暂时不用考虑。
我们点击“扫码登录”,然后鼠标放在密码的文本框上,右键选择检查,可以看到:

FORM中隐藏表单中的lt,execution等都已经填入了相关值。你可以进一步做实验,每次刷新login页面,这些值都会变化。我们发现fkid这个新属性(csdn最新添加的属性)并没有值。仍是value。我们参考Python3网络爬虫开发实战中的方法编写如下代码取出隐藏表单的值:
这里面用到XPATH。
如何知道XPATH,直接在F12模式的表单input位置,右键选择copy XPATH即可。
import urllib.request
import requests
from lxml import etree
#获取加载的it/execution/fkid等的值
headers = {
'Referer': 'https://www.csdn.net/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5193.400 QQBrowser/10.0.1066.400',
'Host': 'passport.csdn.net'
}
login_url="https://passport.csdn.net/account/login"
session = requests.Session()
response = session.get(login_url, headers=headers)
selector=etree.HTML(response.text)
execution=selector.xpath('//input[@name="execution"]/@value')[0]
print (execution)
_eventId=selector.xpath('//input[@name="_eventId"]/@value')[0]
print (_eventId)
lt=selector.xpath('//input[@name="lt"]/@value')[0]
print (lt)
fkid=selector.xpath('//*[@id="fkid"]/@value')[0]
print (fkid)

可以看到,fkid的值根本不存在。这个时候,我们就要思考post数据中明明发出了fkid值,为什么这里不存在。(因为运行js代码更新的表单数据是不能通过在网页中抓取的。)
我们查看网页预加载的几个js文件,找到如下js代码:
https://csdnimg.cn/release/passport/history/js/apps/login.js?v=1.3.9
它里面有:


也即初始化的时候,就为登录按钮注册了一个onclick函数,执行的内容是,检查用户名,检查密码,然后计算fkid的值。
我们下断点,然后在浏览器中随便输入abd作为用户名,随便输入abd作为密码。
然后跟踪到81行代码处。
到达断点位置以后,在console控制台取出真正的fkid值。

SMSdk是csdn开发者加入到window属性中的。
将鼠标放在SMSdk上,会显示其中的getDeviceId方法,

鼠标放在getDeviceId上,右键show function definition

可以看到代码被混淆了,目的的就是防止被别人看。
用python写一个功能完全相同的代码不太现实。如果知道机制,还可以用python从网页中取出某些元素,然后算出fkid,传回服务器,同用户名、密码一起形成验证。但是现在不知道机制,就连计算的js代码都被混淆了。
于是:第一,输入是什么,也就是从页面中取出哪些值进行计算,这个不确定。我猜测csdn取得就是webflow的流水号,你可以看csdn的登录页面的源码。第二,运算过程怎么样,也不知道。
这个时候,只能用python执行js程序。这个时候想到了node.js。
具体过程不在展开。你会发现遇到一个问题,就是直接调用混淆化后的js代码,会提示window没有定义。因为node.js中使用的是global作为全局属性,而window则是浏览器中才有的。
也就是说,会发现没法用node.js执行这些js代码。所以这种直接用python去模拟这么复杂的验证过程,比较困难。选择采用一些能够模拟浏览器的框架。注意,不单纯是模拟发送请求,接收返回的urllib包,而是模拟浏览器行为!这些就是针对类似csdn这种有复杂验证机制的爬虫。
于是就产生了第三篇博文,
3 使用selenium模拟登录csdn
用selenium进行模拟登录,保存cookie。
2 模拟登录_Post表单方式(针对chinaunix有效,针对csdn失效,并说明原因)的更多相关文章
- C#的提交表单方式主要有两种WebClient与HttpWebRequest
根据黄聪:C#模拟网站页面POST数据提交表单(转) using System; using System.Collections.Generic; using System.IO; using Sy ...
- C# 模拟提交 Form表单的数据
用 HttpWebRequest Post方法模拟提交Form表单数据时,需要设置 ContentType 为 "application/x-www-form-urlencoded" ...
- C#模拟POST提交表单(一)--WebClient
C#的提交表单方式主要有两种WebClient与HttpWebRequest,这里先介绍一种 WebClient,转送门:http://msdn.microsoft.com/zh-cn/library ...
- 基于HTML5手机登录注册表单代码
分享一款基于HTML5手机登录注册表单代码.这是一款鼠标点击注册登录按钮弹出表单,适合移动端使用.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class=&qu ...
- ajaxSubmit 页面生成的html 中含有表单提交表单方式
$("#form_title").ajaxSubmit({ //页面生成的html 中含有表单提交表单方式 dataType: "json", success ...
- java 模拟表单方式提交上传文件
/** * 模拟form表单的形式 ,上传文件 以输出流的形式把文件写入到url中,然后用输入流来获取url的响应 * * @param url 请求地址 form表单url地址 * @param f ...
- jquery的ajax提交form表单方式总结
方法一: function AddHandlingFeeToRefund() { var AjaxURL= "../OrderManagement/AjaxModifyOrderServic ...
- 邮箱登录form表单样例
index.html <!doctype html> <html lang="en"> <head> <meta charset=&quo ...
- 大型运输行业实战_day05_1_登录+注销+表单重复提交+登录拦截器
1.登录 登录实现如下步骤: 1.在首页中添加登录按钮 html代码如下: <%@ page contentType="text/html;charset=UTF-8" la ...
随机推荐
- Zynq-7000 FreeRTOS(二)中断:PL中断请求
总结Zynq-7000的PL发送给PS一个中断请求,为FreeRTOS中断做准备. UG585的P225显示了系统的中断框图,如下图所示. 图:ZYNQ器件的中断框图 UG585的P227画出来中断控 ...
- JDK7 AutoCloseable
干嘛的 直接看JDK7的流(运用了AutoCloseable)源码 public abstract class InputStream implements Closeable { //实现Close ...
- django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty
https://www.e-learn.cn/content/wangluowenzhang/165461 问题: I created a new project in django and past ...
- (转)C# 正则表达式
最近写爬虫时需要用到正则表达式,有段时间没有使用正则表达式现在渐渐感觉有些淡忘,现在使用还需要去查询一些资料.为了避免以后这样的情况,在此记录下正则表达式的一些基本使用方法附带小的实例.让以后在使用时 ...
- 使用NHibernate(4)--拦截器和事件
如果想在一个事务的开始.执行中.完成后等过程中执行一些自己的逻辑(比如记录日志.查看sql),拦截器(Interceptors)和事件(Event)就可以发挥作用了.两者所能完成的功能差不多. 1,拦 ...
- 如何修改 linux ubuntu 默认语言
最近学习linux中,由于安装时选择了简体中文作为默认语言,时常出现乱码现象,所以决定将默认语言改回en_US. 但是在网上找了一些教程,发觉不一定都能实现.现总结如下: (1)对于大部分linux系 ...
- [PY3]——Python的函数
Python函数总结图 1.调用 1.1 如何调用 1.1.1 函数名(传参) # 函数使用函数名来调用,函数名后紧跟一对小括号,小括号里传入函数定义时要求的参数 add(9,9) #9+9=18 ...
- 转载:BIO | NIO | AIO
http://my.oschina.net/bluesky0leon/blog/132361 也谈BIO | NIO | AIO (Java版) 转载自:zheng-lee博客 发布时间: 201 ...
- [转]jquerUI Dialog中隐藏标题栏的关闭"X"按钮
本文转自:http://blog.chinaunix.net/uid-144593-id-2804206.html 方法1. 在CSS文件中添加如下样式既可 .ui-dialog-titlebar-c ...
- table中td 内容超长 自动折行 (含字母数字文字)
<table style="width:100%;table-layout:fixed;"> //列宽由表格宽度和列宽度设定 <thead> <th& ...