之前就提到过,简单的采集办法对JS和登录表单的网站无可奈何,网站在获取表单和进行登录这一过程的时候,都是使用HTTP协议的Get方法去请求信息,这样可以通过POST方法,把信息推送给网络服务器进行存储和分析。
页面的表单基本上可以看成是一种用户提交Post请求的方式,而且这种方式是服务器可以理解和使用的,就像网站的URL链接可以帮助用户发送GET请求一样,HTML表单可以帮助用户发出Post请求。在这之前得说下我们一直在用的库:
Python Request库
之前的采集使用Python标准库urllib库,基本搞定了所有的事情,而Request库作为一个能够处理复杂http请求、cookie、header这些内容的第三方库,在进行采集之前记得安装(日常pycharm偷懒。可以pip亦或下载:https://github.com/kennethreitz/requests/tarball/master)
提交一个基本表单
大多数的网页的表单都是由一些html字段,一个提交按钮、一个在表单处理完之后跳转的“执行结果”(Action值),虽然其中的html字段通常是由文字构成的,但是也可以实现文件的上传或其他非文字内容。(由于我尝试的几个网站好像都BAN了爬虫接入登录表单//详情你百度robots.txt你就知道了,在做站长SEO的时候就有这个文件的配置,可以让百度蜘蛛明白什么是可以爬取的,什么是不可以爬取的。所以后面的所有例子我就自己在本地尝试了)
做两个JSP 一个拥有登录表单,一个 用于显示登录后的信息:
<body> <form method="post" action="<%=request.getContextPath()%>/succeed.jsp"> First name: <input type="text" name="firstname"><br> Last name: <input type="text" name="lastname"><br> <input type="submit" value="Submit"> </form> </body>
<body> <h2> Hello,<%=request.getParameter("firstname")%>.<%=request.getParameter("lastname")%></h2> <h1>Welcome to There</h1> </body>
import requests params = {'firstname': 'Kelovp', 'lastname': 'Strings'} r = requests.post("http://localhost:8080/Scapcy/succeed.jsp", data=params) print(r.text)
嗨哟。虽然提交表单在index.jsp当中,而其最终指向的是succeed.jsp,所以在这里直接提取得到以下:
也就是说你如果能搞定用于提交的From表单结构,那就可以随意注入使用(所以现实中有了验证码-=-)
而以上就是简单的提交from表单了。
单选按钮、复选框和其他输入
然而html内容的提交可不简单的包括from表单,给你一个文本框,在附带一个按钮,让你人性而舒服的输入,HTML标准当中提供了大量可用的表单字段:单选按钮、复选框还有像下拉选框没的。在H5当中还包含其他控件,像滚动条、邮箱、日期等。而自定义的JavaScript字段则是无所不能,可以实现取色器、日历以及开发者能想到的任何功能。
这里只说个简单的例子,由于情况的不同可能会有不同的结果出现:
我在搜索框键入Kelovp之后点击搜索,在开始响应的时候查看得到的这个Query String Parameters即URL中携带提交的东西,也就是我上面的那个firstname:
所以这一选项视具体情况而定。
处理登录和Cookies
大多数新式的网站都用 cookie 跟踪用户是否已登录的状态信息。一旦网站验证了你的登录权证,它就会将它们保存在你的浏览器的 cookie 中, 里面通常包含一个服务器生成的令牌、登录有效时限和状态跟踪信息。 网站会把这个 cookie 当作信息验证的证据,在你浏览网站的每个页面时出示给服务器。
依旧是熟悉的味道:之前的Selvet登录正好拿来使用:
import requests session = requests.Session() params = {'uname': 'sa', 'upwd': '123456','submit':'\u63d0\u4ea4'} s = session.post("http://localhost:8080/shopping/login.jsp", params) print("Cookie is set to:") print(s.cookies.get_dict()) print("-----------") print("Going to Hello page...") s = session.get("http://localhost:8080/shopping/hello.jsp") print(s.text)
这里所采取的办法和之前也是极为相似。
而跨窗口提取多是通过 get/post的办法来注入,还是通过验证的一个手段。