第三章--Urllib库与URLError异常处理

快速使用Urllib爬取网页

Urllib库是Python提供的一个用于操作URL的模块。使用Urllib爬取网页,首先需要导入用到的模块,在这里我们要导入urllib.request这个模块,然后我们使用urllib.request.urlopen爬取百度首页(源代码),爬取后将爬到的网页赋给了file:

import urllib.request
#爬取一个网页
file = urllib.request.urlopen('http://www.baidu.com')
data = file.read()
print(data)

上面这段代码就爬取了百度的首页,但是输出的是一串代码,下面就将爬取到的东西以网页的形式保存到本地:

#以二进制方式打开
fhandle = open("D:/something/baidu.html", "wb")
fhandle.write(data)
fhandle.close()

执行完这段代码就可以输出一个HTML文件,然后通过浏览器打开这个文件就可以看到百度的界面。

除了这种方法我们还可以使用urllib.request中的urlretrieve()函数直接将对应信息存入本地,格式为:

filename = urllib.request.urlretrieve("http://edu.51cto.com", filename="D:/something/51cto.html")

urlretrieve执行的过程中会产生一些缓存,如果我们想清除这些缓存信息可以使用urcleanup()进行清除,输入如下代码可以清除缓存:

urllib.request.urcleanup()

urllib常见的用法:

浏览器的模拟--Headers属性

有的时候,我们无法爬取一些网页,会出现403错误,因为这些网页为了防止别人恶意采集其信息所以进行了一些反爬虫的设置,如果我们想爬取这些信息应该怎么办呢?

可以设置一些Headers信息,模拟成浏览器去访问这些网站,此时就能够解决这些问题。(这段先不补充,书上的东西有一些问题)

超时设置

有时候我们在访问一个网页的时候,如果网页长时间没有响应,那么系统就会判断该网页超时了即无法打开网页。有时候我们需要根据自己需要来设置超时的时间值,比如有些网页反应快我们希望10秒钟作为判断是否超时的标准,timeout就是10;再比如有些网站服务器比较慢我们希望80秒作为标准,那么timeout的值就是80。

格式:urllib.request.urlopen(要打开的网页, timeout = 时间值)

import urllib.request
for i in range(1, 100):
    try:
        file = urllib.request.urlopen("http://yum.iqianyue.com", timeout=1)   #设置时间为1秒钟,即超过一秒钟没有加载网页页面即可认为超时
        data = file.read()
        print(len(data))
    except Exception as e:
        print("出现异常--->", str(e))
输出如下:
出现异常---> <urlopen error timed out>
出现异常---> <urlopen error timed out>
14165
14165
14165
14165
14165
14165
14165
14165
14165
14165
14165
14165
出现异常---> timed out
14165
14165
出现异常---> <urlopen error timed out>

HTTP协议请求实战

如果要进行客户端和服务端之间的消息传递,我们可以使用HTTP协议请求进行。

HTTP协议主要分为6种类型,各类型的主要功能如下;

  • GET请求:GET请求会通过URL网址传递信息,可以直接在URL中写上要传递的信息,也可以由表单进行传递。如果使用表单进行传递,这表单中的信息会自动转为URL地址中的数据,通过URL地址传递
  • POST请求:可以向服务器提交数据,是一种比较主流也比较安全的数据传递方式,比如在登录时,经常使用POST请求发送数据
  • PUT请求:请求服务器存储一个资源,通常要指定存储的位置
  • DELETE请求:请求服务器删除一个资源
  • HEAD请求:请求获取对应的HTTP报头信息
  • OPTIONS请求:可以获得当前URL所支持的类型

GET请求实例分析

有时想在百度上查询一个关键字,我们首先会打开百度首页,并输入该关键字进行查询,那么这个过程是怎么实现的呢?

通过分析发现对应的额查询信息是通过URL传递的,这里说采用的是HTTP请求中的GET方法,我们将网页提取出来进行分析,该网址为https://www.baidu.com/s?wd=hello&rsv_spt=1&rsv_iqid=0xd2564b4b00028c19&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=8&rsv_sug1=7&rsv_sug7=101&rsv_sug2=0&inputT=2271&rsv_sug4=1893237

ie=utf-8表示编码信息,wd=hello表示我们要查找的信息。这样的话如果我们直接对网址进行简化,简化成https://www.baidu.com/s?wd=hello,此时只包含了我们要查找的信息,我们把这个新的网址放到百度首页发现一样可以执行。由此可见我们在百度上查询一个关键词会用GET请求进行。

根据分析出的这个规律,即可以构造GET请求,使用爬虫在网站上自动查询某个关键字。

import urllib.request
keywd = "hello"
url = "http://baidu.com/s?wd=" + keywd
#创建了一个Request对象并赋值给变量req
req = urllib.request.Request(url)
#通过urlopen()函数进行读取数据
data = urllib.request.urlopen(req).read()
print(data)
fhandle = open("D:/something/hello1.html","wb")
fhandle.write(data)
fhandle.close()

POST请求实例分析

这里提供一个测试网页:http://www.iqianyue.com/mypost/。打开对应网址,发现有一个表单,输入数据并单击提交可以发现我们提交的数据会通过POST方法传递给下方显示,那怎么通过爬虫实现这个过程呢?实现的思路如下:

  • 设置好URL地址
  • 构建表单数据,并用urllib.parse.urlencode对数据进行编码处理
  • 创建Request对象,参数包括URL地址和要传递的数据
  • 创建add_header()添加头信息,模拟浏览器进行爬取
  • 使用urllib.request.urlopen()打开对应的Request对象,完成信息的传递
  • 后续处理,比如读取网页内容、将内容写入文件等等
import urllib.request
import urllib.parse
url = "http://www.iqianyue.com/mypost/"
postdata = urllib.parse.urlencode({
    "name":"[email protected]",
    "pass":"aA123456"
}).encode('utf-8')   #将数据使用urlencode编码处理后,使用encode()设置为utf-8编码
req = urllib.request.Request(url, postdata)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36')
data = urllib.request.urlopen(req).read()
print(data)
fhandle = open("D:/something/iqianyue.html", "wb")
fhandle.write(data)
fhandle.close()

代理服务器的设置

有时候用同一个IP去爬取同一个网站上的网页,久了之后会被该网站服务器所屏蔽,那么怎么解决这个问题呢?

如果我们爬取别人的网站,对方显示器上显示的是别人的IP地址,那么即使对方将显示出来的这个IP屏蔽了,也无关紧要,我们可以换另一个IP地址继续爬取。

使用代理服务器就可以很好的解决这个问题。使用代理服务器去爬取某个某个网站的内容的时候,在对方的电脑上显示的不是我们真正的IP地址,而是代理服务器的地址。并且在Python爬虫中,使用代理服务器也非常简单。

代理服务器地址:

我们在其中随便选择一个代理IP地址,比如58.215.140.6,对应的端口号是8080,完成的格式为:"网站:端口号"。即58.215.140.6:8080。

通过下面代码实现代理服务器爬取网站内容:

#定义一个函数,主要用于使用代理服务器来爬取某个网页的功能
def use_proxy(proxy_addr, url):
    import urllib.request
    #通过ProxyHandler函数来设置对应的代理服务器信息设置格式为:函数名(‘http’: 代理服务器名称)
    proxy = urllib.request.ProxyHandler({'http':proxy_addr})
    #创建一个opener对象,第一个参数为代理信息,第二个参数为urllib.request.HTTPHandler()类
    opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
    #创建全局默认的opener对象
    urllib.request.install_opener(opener)
    
    data = urllib.request.urlopen(url).read().decode('utf-8')
    return data

proxy_addr = '58.215.140.6:8080'
data = use_proxy(proxy_addr, "http://www.baidu.com")
print(len(data))

猜你喜欢

转载自blog.csdn.net/weixin_41931540/article/details/85015733
今日推荐