参考内容:1.https://www.cnblogs.com/Lands-ljk/p/5447127.html 2.https://cuiqingcai.com/947.html
1.分分钟扒一个网页下来
怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS、CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML中的,下面我们就写个例子来扒一个网页下来。
from urllib.request import urlopen response=urlopen("http://www.baidu.com") html=response.read().decode(‘utf-8‘) print(html)
是的你没看错,真正的程序就两行,把它保存成 demo.py,进入该文件的目录,执行如下命令查看运行结果,感受一下。
2.分析扒网页的方法
那么我们来分析这两行代码,第一行
response=urlopen("http://www.baidu.com")
首先我们调用的是urllib库里面的request下的urlopen方法,传入一个URL,这个网址是百度首页,协议是HTTP协议,当然你也可以把HTTP换做FTP,FILE,HTTPS 等等,只是代表了一种访问控制协议,urlopen一般接受三个参数。使用方法如下:
urllib.request.
urlopen
(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
- url: 需要打开的网址
- data:Post提交的数据
- timeout:设置网站的访问超时时间
第一个参数URL是必须要传送的,在这个例子里面我们传送了百度的URL,执行urlopen方法之后,返回一个response对象,返回信息便保存在这里面。
如果不加read:直接打印出了该对象的描述。所以记得一定要加read方法,否则它不出来内容可就不怪我咯!
直接用urllib.request模块的urlopen()获取页面,page的数据格式为bytes类型,需要decode()解码,转换成str类型。
1 from urllib import request 2 response = request.urlopen(r‘http://python.org/‘) # <http.client.HTTPResponse object at 0x00000000048BC908> HTTPResponse类型 3 page = response.read() 4 page = page.decode(‘utf-8‘)
urlopen返回对象提供方法:
- read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作
- info():返回HTTPMessage对象,表示远程服务器返回的头信息
- getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
- geturl():返回请求的url
3.构造Request
其实上面的urlopen参数可以传入一个request请求,它其实就是一个Request类的实例,构造时需要传入Url,Data等等的内容。比如上面的两行代码,我们可以这么改写
from urllib import request req=request.Request("http://www.baidu.com") print(req) response=request.urlopen(req) html=response.read() html = html.decode(‘utf-8‘) print(html)
运行结果是完全一样的,只不过中间多了一个request对象,推荐大家这么写,因为在构建请求时还需要加入好多内容,通过构建一个request,服务器响应请求得到应答,这样显得逻辑上清晰明确。
urllib.request.
Request
(url, data=None, headers={}, method=None)
使用request()来包装请求,再通过urlopen()获取页面。
再比如:
url = r‘http://www.lagou.com/zhaopin/Python/?labelWords=label‘ headers = { ‘User-Agent‘: r‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ‘ r‘Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3‘, ‘Referer‘: r‘http://www.lagou.com/zhaopin/Python/?labelWords=label‘, ‘Connection‘: ‘keep-alive‘ } req = request.Request(url, headers=headers) page = request.urlopen(req).read() page = page.decode(‘utf-8‘)
用来包装头部的数据:
- User-Agent :这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言
- Referer:可以用来防止盗链,有一些网站图片显示来源http://***.com,就是检查Referer来鉴定的
- Connection:表示连接状态,记录Session的状态。
4.POST和GET数据传送
上面的程序演示了最基本的网页抓取,不过,现在大多数网站都是动态网页,需要你动态地传递参数给它,它做出对应的响应。所以,在访问时,我们需要传递数据给它。最常见的情况是什么?对了,就是登录注册的时候呀。
把数据用户名和密码传送到一个URL,然后你得到服务器处理之后的响应,这个该怎么办?下面让我来为小伙伴们揭晓吧!
数据传送分为POST和GET两种方式,两种方式有什么区别呢?
最重要的区别是GET方式是直接以链接形式访问,链接中包含了所有的参数,当然如果包含了密码的话是一种不安全的选择,不过你可以直观地看到自己提交了什么内容。POST则不会在网址上显示所有的参数,不过如果你想直接查看提交了什么就不太方便了,大家可以酌情选择。
(1)POST
urllib.request.
urlopen
(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
urlopen()的data参数默认为None,当data参数不为空的时候,urlopen()提交方式为Post。
一个例子:
from urllib import request, parse url = r‘http://www.lagou.com/jobs/positionAjax.json?‘ headers = { ‘User-Agent‘: r‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ‘ r‘Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3‘, ‘Referer‘: r‘http://www.lagou.com/zhaopin/Python/?labelWords=label‘, ‘Connection‘: ‘keep-alive‘ } data = { ‘first‘: ‘true‘, ‘pn‘: 1, ‘kd‘: ‘Python‘ } data = parse.urlencode(data).encode(‘utf-8‘) req = request.Request(url,data=data, headers=headers, ) page = request.urlopen(req).read() page = page.decode(‘utf-8‘) print(page)
urllib.parse.urlencode
(query, doseq=False, safe=‘‘, encoding=None, errors=None)
urlencode()主要作用就是将url附上要提交的数据。
data = { ‘first‘: ‘true‘, ‘pn‘: 1, ‘kd‘: ‘Python‘ } data = parse.urlencode(data).encode(‘utf-8‘)
经过urlencode()转换后的data数据为?first=true?pn=1?kd=Python,最后提交的url为
http://www.lagou.com/jobs/positionAjax.json?first=true?pn=1?kd=Python
Post的数据必须是bytes或者iterable of bytes,不能是str,因此需要进行encode()编码
当然,也可以把data的数据封装在urlopen()参数中。
另一个例子:
现在我们要模拟登陆CSDN:当然下面代码可能登陆不进去,因为CSDN还有个流水号的字段,没有设置全,比较复杂在这里就不写上去了,在此只是说明登录的原理。一般的登录网站一般是这种写法。
values={‘username‘:"xxxxx@qq.com","password":"xxxx"} data=parse.urlencode(values).encode(‘utf-8‘)
我们需要定义一个字典,名字为values,参数我设置了username和password,下面利用urllib的urlencode方法将字典编码,命名为data,构建request时传入两个参数,url和data,运行程序,返回的便是POST后呈现的页面内容。
(2)GET
至于GET方式我们可以直接把参数写到网址上面,直接构建一个带参数的URL出来即可。
values={‘username‘:"xxxxx@qq.com","password":"xxxx"} data=parse.urlencode(values).encode(‘utf-8‘) url="http://passport.csdn.net/account/login" geturl=url+"?"+data req = request.Request(geturl ) page = request.urlopen(req).read() page = page.decode(‘utf-8‘) print(page)
你可以print geturl,打印输出一下url,发现其实就是原来的url加?然后加编码后的参数
和我们平常GET访问方式一模一样,这样就实现了数据的GET方式传送。