Python 爬虫学习稿(一)
2016-01-10 00:52
591 查看
本次学习的环境是基于Python 3.3.5,实验的工具是Pycharm 5.0.1
基础的知识我就不再介绍,比如HTTP的基础知识、爬虫的相关背景
直接开始爬虫的学习吧!
urlopen()可以接收三个参数即
url即你要请求的url地址,data是访问这个url需要传送的数据,timeout是超时时间
url是必填参数,其余两个是可选参数
urllib.request.urlopen(url)会返回一个http.client.HTTPResponse对象
这个返回的对象可以使用read()方法,来返回数据
这样一个脚本就可以让我们得到所填入的
如果我们不调用read这个方法,会打印出什么呢?会打印出下面这样一行
这样就直接把这个对象的描述打印出来了,而不是具体内容了
这样也是完全相同的效果,我们必须注意的是库是区分大小写的,Request写成request是不能被识别的,会报错
这样我们就完成了构建一个request,然后得到服务器对请求的应答,这样更符合直观的逻辑
需要说明的是,urllib.request.Request()是统一处理所有URL头的方法,你可以直接使用
值得注意的是,编码所使用的库为urllib的函数而不是像之前的程序可以只引用一个urllib2库就可以了,Python 3.X的版本和和之前的2.X的版本差距还是真大
遇到这个错误
还必须指出的是,在Python 2.X中所使用的urllib.urlencode并不存在了,只能使用
代码如下
你需要替换成一个你可以登录的URL地址,就可以进行测试了,或者你可以在本地自己搭建一个最简单的CGI脚本来进行测试
上面这个方法是使用POST来进行传递表单数据时,下面介绍GET如何进行表单数据的传送
Python3对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示,二者不能混用。
所以你如果这样执行的话,必然遇到错误
使用.decode()进行解码,就能将byte型的data转换成str型,geturl就统一为str型就可以进行连接了。这样就可以成功执行了,只不过同上一个一样,你需要找一个能够成功的 URL地址
浏览器会把自己的标识发给服务器,但是urllib默认是显示python-urllib,这样会导致服务器不予以响应,那么我们可以显式的指定headers里的字段,下面列举了常见的一些字段:
User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求
Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务
application/xml : 在 XML RPC,如 RESTful/SOAP 调用时使用
application/json : 在 JSON RPC 调用时使用
application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用
所以我们修改一个User-Agent作为范例
还可以继续修改Referer,这样可以反反盗链
有时候不得不使用代理服务器来避免一个IP访问请求过多遭到禁止,那么如何设置代理就是一门学问,这里简明写个小例子
基础的知识我就不再介绍,比如HTTP的基础知识、爬虫的相关背景
直接开始爬虫的学习吧!
一、用Python抓取指定页面
常见的urllib2库在Python3.X的版本中改名啦!叫urllib.request了!urlopen()可以接收三个参数即
urlopen(url, data, timeout)
url即你要请求的url地址,data是访问这个url需要传送的数据,timeout是超时时间
url是必填参数,其余两个是可选参数
urllib.request.urlopen(url)会返回一个http.client.HTTPResponse对象
这个返回的对象可以使用read()方法,来返回数据
# encoding: utf-8 import urllib.request response = urllib.request.urlopen("http://www.baidu.com") print(response.read())
这样一个脚本就可以让我们得到所填入的
www.baidu.com这个网址的网页源码,你可以开启浏览器,然后按下F12来对照看是不是一样
如果我们不调用read这个方法,会打印出什么呢?会打印出下面这样一行
<http.client.HTTPResponse object at 0x0314B690>
这样就直接把这个对象的描述打印出来了,而不是具体内容了
二、构造Request
根据我们的习惯,我们应该当传入一个request的实例,我们可以改写上面的代码为# encoding: utf-8 import urllib.request request = urllib.request.Request("http://www.baidu.com") response = urllib.request.urlopen(request) print(response.read())
这样也是完全相同的效果,我们必须注意的是库是区分大小写的,Request写成request是不能被识别的,会报错
这样我们就完成了构建一个request,然后得到服务器对请求的应答,这样更符合直观的逻辑
需要说明的是,urllib.request.Request()是统一处理所有URL头的方法,你可以直接使用
ftp://baidu.com也是可以的
三、传递表单数据
Web传递表单数据的常见方式有POST和GET两种方式,我们可以构造一个表单作为data,然后编码成标准形式,作为参数传递给Request对象值得注意的是,编码所使用的库为urllib的函数而不是像之前的程序可以只引用一个urllib2库就可以了,Python 3.X的版本和和之前的2.X的版本差距还是真大
遇到这个错误
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str时,是需要在url编码后再使用utf-8进行编码,否则会出现这个类型错误。修改方法是)
urllib.parse.urlencode(values).encode(encoding='UTF8')
还必须指出的是,在Python 2.X中所使用的urllib.urlencode并不存在了,只能使用
urllib.parse.urlencode进行替换
代码如下
# encoding: utf-8 import urllib import urllib.request value = {"username" : "teacher" , "password" : "123456789"} data = urllib.parse.urlencode(value).encode(encoding='UTF8') url = "http://mail.qinghua.edu.cn/login?" request = urllib.request.Request(url , data) response = urllib.request.urlopen(request) print(response.read())
你需要替换成一个你可以登录的URL地址,就可以进行测试了,或者你可以在本地自己搭建一个最简单的CGI脚本来进行测试
上面这个方法是使用POST来进行传递表单数据时,下面介绍GET如何进行表单数据的传送
# encoding: utf-8 import urllib import urllib.request value = {"username" : "teacher" , "password" : "123456789"} data = urllib.parse.urlencode(value).encode(encoding='UTF8') url = "http://mail.qinghua.edu.cn/login" geturl = url + "?" + data request = urllib.request.Request(geturl) response = urllib.request.urlopen(request) print(response.read())
Python3对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示,二者不能混用。
所以你如果这样执行的话,必然遇到错误
TypeError: Can't convert 'bytes' object to str implicitly因为此时的data是byte型的,而url是str型的,两者不能连接起来的,需要把byte型的data转换成str型
# encoding: utf-8 import urllib import urllib.request value = {"username" : "teacher" , "password" : "123456789"} data = urllib.parse.urlencode(value).encode(encoding='UTF8') url = "http://mail.qinghua.edu.cn/login" geturl = url + "?" + data.decode() request = urllib.request.Request(geturl) response = urllib.request.urlopen(request) print(response.read())
使用.decode()进行解码,就能将byte型的data转换成str型,geturl就统一为str型就可以进行连接了。这样就可以成功执行了,只不过同上一个一样,你需要找一个能够成功的 URL地址
四、设置Headers构建HTTP请求
我们都知道,对不同的浏览器,网页端可以进行分别适配以达到最佳的浏览体验,还有一些像微信中的某些连接只能用微信中的浏览器打开的,如果你用电脑的浏览器就无法打开,所以我们可以对Headers头进行设置来构建HTTP请求浏览器会把自己的标识发给服务器,但是urllib默认是显示python-urllib,这样会导致服务器不予以响应,那么我们可以显式的指定headers里的字段,下面列举了常见的一些字段:
User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求
Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务
application/xml : 在 XML RPC,如 RESTful/SOAP 调用时使用
application/json : 在 JSON RPC 调用时使用
application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用
所以我们修改一个User-Agent作为范例
# encoding: utf-8 import urllib import urllib.request user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' value = {"username" : "teacher" , "password" : "123456789"} data = urllib.parse.urlencode(value).encode(encoding='UTF8') headers = {'User-Agent' : user_agent} url = "http://mail.qinghua.edu.cn/login?" request = urllib.request.Request(url , data, headers) response = urllib.request.urlopen(request) print(response.read())
还可以继续修改Referer,这样可以反反盗链
# encoding: utf-8 import urllib import urllib.request user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' value = {"username" : "teacher" , "password" : "123456789"} data = urllib.parse.urlencode(value).encode(encoding='UTF8') headers = {'User-Agent' : user_agent , 'Referer': 'http://mail.qinghua.edu.cn/'} url = "http://mail.qinghua.edu.cn/login?" request = urllib.request.Request(url , data, headers) response = urllib.request.urlopen(request) print(response.read())
五、关于其他
timeout的设置,如果有的网站响应速度过慢,可以通过设置timeout来避免无限制等待响应,之前也说过,urlopen的第三个参数就是timeout,显式设置即可有时候不得不使用代理服务器来避免一个IP访问请求过多遭到禁止,那么如何设置代理就是一门学问,这里简明写个小例子
# encoding: utf-8 import urllib.request enable_proxy = True proxy_handler = urllib.request.ProxyHandler({"http" : 'http://some-proxy.com:8080'}) null_proxy_handler = urllib.request.ProxyHandler({}) if enable_proxy: opener = urllib.request.build_opener(proxy_handler) else: opener = urllib.request.build_opener(null_proxy_handler) urllib.request.install_opener(opener)
相关文章推荐
- 关于python 文件操作os.fdopen(), os.close(), tempfile.mkstemp()
- python2.7---查询信息代码
- python轻松查到删除自己的微信好友
- 详解Python发送邮件实例
- Python 虚拟环境Virtualenv
- python之路-模块 WebDriver API
- python routes
- python学习之简单正则与爬虫
- Python pip 更新问题汇总
- 【学神-RHEL7】P2-Python流程控制
- [Python标准库]operator——内置操作符的函数接口
- Python读写文件实际操作的五大步骤
- 菜鸟学python(8) 初识函数
- Python多进程编程
- python基础学习——第二天
- 高阶函数简单总结记录
- python发送邮件方法
- python 位运算符与逻辑运算符(字符串的逻辑运算)
- 比较Python和Perl的效率
- leetcode之Reverse Linked List II