python爬虫

Python 爬虫知识记——基础篇

2016-12-08  本文已影响2991人  行走的老者
简单的爬虫请求:
# 注意在python3.3以上,用urllib.request替换了之前的urllib2
import urllib.request

request = urllib.request.Request("https://github.com/JackLiaoJH/ImageSelect")
# urllib.request.urlopen(url,data,timeout) :第一个参数url,第二个参数是访问url要传送的数据,第三个参数是设置超时的时间
response = urllib.request.urlopen(request)
print(response.read())

这样就会获取到指定网页的数据了。

GET 请求模拟

import urllib.request
import urllib.parse
import urllib

# get请求
values = {"username": "100000000@qq.com", "password": "23456"}
dataGet = urllib.parse.urlencode(values)
urlGet = "https://www.oschina.net/home/login" + "?" + dataGet
requestGet = urllib.request.Request(urlGet)
responseGet = urllib.request.urlopen(requestGet)
print(responseGet.read().decode('UTF-8'))

post 请求模拟

import urllib.request
import urllib.parse
import urllib

# post请求,比如登录开源中国
params = {"username": "100000000@qq.com", "password": "23456"}
data = urllib.parse.urlencode(params)
url = "https://www.oschina.net/home/login?goto_page=https%3A%2F%2Fwww.oschina.net%2F";
request1 = urllib.request.Request(url)
response1 = urllib.request.urlopen(request1)
print(response1.read())

headers 请求头设置

下面先看访问开源中国登录界面,这个界面包含了很多信息,可以按f12查看请求细节,下面是请求截图:


请求网址头部.png

在urllib.request.Request(urlGet, data, headers)这个方法里面设置data,header。

例子:

# get请求设置请求头
values = {"username": "100000000@qq.com", "password": "23456"}
dataGet = urllib.parse.urlencode(values)
urlGet = "https://www.oschina.net/home/login" + "?" + dataGet
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) Chrome/56.0.2924.10 Safari/537.36",
           "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"}
requestGet = urllib.request.Request(urlGet, None, headers)
responseGet = urllib.request.urlopen(requestGet)
print(responseGet.read().decode('UTF-8'))

另外为了对付防盗链,对方服务器会事变header中的Referer是不是自己的,所以我们会在头部中加上Referer,如:

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) Chrome/56.0.2924.10 Safari/537.36",
       "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
       "Referer": "https://www.oschina.net/"}

在进行爬虫时我们还需要注意其他相关参数,设置错误,服务器会拒绝我们访问,所以要仔细看好请求头所需要的必须字段。

urllib 的高级用法

Proxy (代理)的设置

urllib.request默认会使用环境变量http_proxy来设置Http 代理,所以我们可以通过这个来设置一些代理服务器,每隔一段时间换一个代理去爬取数据,这个就可以防止你的ip由于过多访问被禁止访问的风险,设置方法如下:

import urllib.request

enable_proxy = True
# 设置代理服务器
proxy_handler = urllib.request.ProxyHandler({"http": 'http://proxy_xxx.com:8090'})
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)
TimeOut 设置

为了解决我们在爬取时由于服务器响应过慢而造成的影响,我们可以设置我们自己的超时时间,防止一直占用资源,设置也非常简单,代码如下:

# 如果第二个参数data为空,则需要指定timeout=多少,若data已传入,则不需要指明
response = urllib.request.urlopen('http://www.baidu.com',data, 10)
response = urllib.request.urlopen('http://www.baidu.com',timeout=10)
UrlError

在爬取时,由于种种原因会导致失败,这个时候我们可以通过try-exception来捕获相关的异常,代码如下:

import urllib.error

request = urllib.request.Request("http://www.i love you.com")
try:
    urllib.request.urlopen(request)
except urllib.error.URLError as e:
    print(e.reason)

报错:[WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

下面重点介绍下HTTPError,HTTPError是UrlError的子类,服务端返回的常见状态吗如下:

100:继续  客户端应当继续发送请求。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。
101: 转换协议  在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。
102:继续处理   由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。
200:请求成功      处理方式:获得响应的内容,进行处理
201:请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到    处理方式:爬虫中不会遇到
202:请求被接受,但处理尚未完成    处理方式:阻塞等待
204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。    处理方式:丢弃
300:该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。    处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301:请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源    处理方式:重定向到分配的URL
302:请求到的资源在一个不同的URL处临时保存     处理方式:重定向到临时的URL
304:请求的资源未更新     处理方式:丢弃
400:非法请求     处理方式:丢弃
401:未授权     处理方式:丢弃
403:禁止     处理方式:丢弃
404:没有找到     处理方式:丢弃
500:服务器内部错误  服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
501:服务器无法识别  服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
502:错误网关  作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503:服务出错   由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。

由于urllib.request可以处理重定向,所以3开头的我们看不到,我们只能看到400以上的错误码,下面取个例子体验下:

import urllib.request
import urllib.error

requestError = urllib.request.Request("http://write.blog.csdn.net/postlist")
try:
    response = urllib.request.urlopen(requestError)
    print(response.read().decode('UTF-8'))
except urllib.error.HTTPError as e:
    print(e.code + "," + e.reason)

还可以这么写,支持多级异常捕获,但是只要前面一级已经捕获到了,就不再往后走了:

import urllib.request
import urllib.error

requestError = urllib.request.Request("http://blog.csdn.net/jackliao1/article/details/52473925")
try:
    response = urllib.request.urlopen(requestError)

except urllib.error.HTTPError as e:
    if hasattr(e, "code"):  # 判断是否有该属性
        print(e.code + "," + e.reason)
except urllib.error.URLError as e:
    print(e.reason)
else:
    print(response.read().decode('UTF-8'))

第一篇就先写到这了,下一篇进行python cookie的处理。

上一篇下一篇

猜你喜欢

热点阅读