有喜欢图像处理,机器学习或者人工智能的人可以加QQ群讨论:
234126428
无奈现在又需要用python做采集,于是自己写一个python采集的技术备忘.
能干什么:
python模拟输入用户名密码登入.登入以后重定向
python模拟发送POST信息来获取页面
python模拟发送GET信息来获取页面由于可以直接在url里面添加信息,所以就不多说了.
相关libs:
cookielib, urllib, urllib2
采集所用的lib:Beautifulsoup (本文止于获得页面,采集部分不提)
工具: 火狐的firebug (chrome的developer tools Ctrl+Shift+I
本文基于火狐的firebug)
采集页面:
http://jp.translink.com.au/travel-information/journey-planner
目的:
用户模拟输入起点和终点,提交表单后得到返回页面
第一步,逻辑分析:
使用firebug或者chrome的developer
tools,查看页面元素.
找到你要输入信息的表单,(form tag).
在form的信息里可以看到网页表单用了什么方法(method): GET/POST
和请求网址是什么(action).
在这个例子里, 方法是POST, 请求网址是根网址+/travel-information/journey-planner
所以第二步里的'url'就是:
http://jp.translink.com.au/travel-information/journey-planner
然后观察表单有哪些input field.
必须要考虑到的input field分三类:
1, 必须输入的field,在这个例子中是起点和终点
2, 默认field.
在这个例子中,有很多网页默认field.
3, 隐藏field.
这些field不再显示的表单中,它隐藏在代码里.
有两种观察方法:
1,用firbug查看form内部的代码,找出所有的field. 每个field的 name就是这个field的"key",
每个field的value使他的值. 可以看到默认field有给出 value
2,用firebug的net板块 (中文firebug叫做网络):
第一次使用需要启用(图一):
启用完了以后会看到如下时间线
图二:
回到页面提交表单,这个时间线会追踪最新页面登入的时候,POST了什么值.
展开第一条信息,可以看到它的头文件:这些头文件信息是登入页面必须/非必需的信息,但是为了保险,在程序里面可以把所有信息附上.(见第二部分,python程序)
图三:
在net(网络)标签下,选择Post.
可以显示这个页面登入的时候,Post了什么信息.上半部分是整理过的信息,下半部分是混合在一起的信息.所有这些信息都必须输入到python模拟提交的程序里.
图四:
第二部分,python程序:
现在就可以开始写程序了.
先准备好Post信息和url. 这些信息来自第一部分:
url =
"http://jp.translink.com.au/travel-information/journey-planner"
para = {
'Start'
: addr2,
'End' :
addr1,
'SearchDate':"19/06/2013
12:00:00 AM",
"TimeSearchMode":"LeaveAfter",
"SearchHour":"6",
"SearchMinute":"05",
"TimeMeridiem":"PM",
"TransportModes":"Bus,Train,Ferry",
"MaximumWalkingDistance":"1500",
"WalkingSpeed":"Normal",
"ServiceTypes":"Regular,Express,NightLink",
"FareTypes":"Free,Standard"
}
python有个很好用的自动处理cookie 的库: cookielib.
它会自动处理cookie部分,所以整个代码如下:
#cookie 处理部分
import cookielib,urllib,urllib2
cj =
cookielib.CookieJar()
opener =
urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
#将post信息encode, 用opener打开页面
login_data =
urllib.urlencode(para)
resp = opener.open(url, login_data)
#这是你返回页面的头文件信息,可以print出来,也可以当dict来用
pageInfo = resp.info()
#这是你返回页面的内容. 可以进一步用Beautifulsoup等库来采集.
pageContent = resp.read()
这就是所有代码.
====================== 讨论 ===========================
1, 如果你print出来 login_data,
你会发现它和第一步中的图四的下半部分一样.也就是说你的post信息可以直接用图四的下半部分所显示的格式.
2, 模拟登入问题:
虽然本文讲的是模拟提交Post, 但是同样的方法可以用在一般的模拟登入上. 只是把POST信息改成账户和密码.
3, 验证码问题:
网上一般对验证码有以下几种办法对付:
3.1, 用开源的办法写或者用全自动机器人进行图像识别.
3.2, 半自动机器人,遇到验证码的时候发到手机或者弹出框框人为输入. 这适合于google那种扭曲的验证码
3.3, 用某种办法绕过验证码.
4, 头文件问题:
这次采集头文件可以忽略,其实在一开始,代码里是有和图三完全一样的头文件部分,后来发现可以忽略,才省略了.有的时候,头文件不可以省略,以下是完整的源代码,包含省略的头文件部分.
url =
"http://jp.translink.com.au/travel-information/journey-planner"
para = {
'Start'
: addr2,
'End'
: addr1,
'SearchDate':"19/06/2013 12:00:00 AM",
"TimeSearchMode":"LeaveAfter",
"SearchHour":"6",
"SearchMinute":"05",
"TimeMeridiem":"PM",
"TransportModes":"Bus,Train,Ferry",
"MaximumWalkingDistance":"1500",
"WalkingSpeed":"Normal",
"ServiceTypes":"Regular,Express,NightLink",
"FareTypes":"Free,Standard"
}
#cookie 处理部分
import
cookielib,urllib,urllib2
cj =
cookielib.CookieJar()
opener =
urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
#将post信息encode, 用opener打开页面
login_data =
urllib.urlencode(para)
resp = opener.open(url, login_data)
#省略的部分:
req = urllib2.Request(url, login_data); # urllib2.Request: the
HTTP request will be a POST instead of a GET when the data
parameter is provided.
#添加头文件
req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel
Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/27.0.1453.110 Safari/537.36');
req.add_header('Content-Type',
'application/x-www-form-urlencoded');
req.add_header('Cache-Control', 'no-cache');
req.add_header('Accept',
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
req.add_header('Connection', 'keep-alive');
req.add_header('Host','jp.translink.com.au')
req.add_header('Origin','http://jp.translink.com.au')
req.add_header('Referer','http://jp.translink.com.au/travel-information/journey-planner')
resp0 = opener.open(req);
respInfo = resp0.info();
respContent = resp0.read()
有喜欢图像处理,机器学习或者人工智能的人可以加QQ群讨论:
234126428