python爬虫网络请求

urlib库

urllib库是Python中一个最基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求 ,并可以保存服务器返回的数据。

urlopen函数

在Python3的urllib库中,所有和网络请求相关的万法,都被集到urllib.request 模块下面了,以先来看下urlopen函数基本的使用:

from urllib import request
resp = request.urlopen('http://www.baidu.com') #ctrl+b 查看参数
print(resp.read())
#print(resp.read(10))
#print(resp.readline())

实际上,使用浏览器访问百度,右键查看源代码。你会发现,跟我们刚才打印出来的数据是一模- 一样的。 也就是说,上面的三行代码就已经帮我们把百度的首页的全部代码爬下来了。一个基本的url请求对应的python代码真的非常简单。
以下对urlopen函数的进行详细讲解:

  1. url :请求的url。

  2. data :请求的data ,如果设置了这个值,那么将变成post 请求。

  3. 返回值:返回值是一个http.client.HTTPResponse 对象,这个对象是个类文件句柄对象。

有read(size)、readline(读取第一行) 、readines(读取多行) 以及getcode(获取状态码)等方法。

urlretrieve函数:

这个函数可以方便的将网页上的一个文件保存到本地。以下代码可以非常方便的将百度的首页下载到本地:

from urllib import request
request.urlretrieve('http://www.baidu.com','baidu.html')

urlencode函数

用浏览器发送请求的时候,如果urI中包含了中文或者其他特殊字符,那么浏览器会自动的给我们进行编码。而如果使用代码发送请求,那么就必须手动的进行编码,这时候就应该使用urlencode函数来实现。urlencode可以把字典数据转换为URL编码的数据。

示例代码如下:

from urllib import parse
data = {
    
    'name':'张三','age':'18','greet':'Hellow Word'}
result = parse.urlencode(data)
print(result)

parse_ qs函数: .

可以将经过编码后的ur|参数进行解码。示例代码如下:

扫描二维码关注公众号,回复: 12252842 查看本文章
from urllib import parse
data = {
    
    'name':'张三','age':'18','greet':'Hellow Word'}
result = parse.urlencode(data)
print(result)
qs = parse.parse_qs(result)
print(qs)

urlparse和urlsplit: .

有时候拿到一个url,想要对这个url中的各个组成部分进行分割,那么这时候就可以使用urlparse或者是ursplit 来进行分割。示例代码如下:

from urllib import parse
url= 'http://www.baidu.com/s;hellow?wd=python&username=adb#1'
result1 = parse.urlparse(url)
result2 = parse.urlsplit(url)
print(result1)
print(result2)  #params参数没有(hellow那部分)
print('scheme:',result.scheme)  #只打印某一项
print('netloc:',result.netloc)

request.Request类:

如果想要在请求的时候增加- -些请求头,那么就必须使用request .Request类来实现。比如要增加-一个User-Agent ,示例代码如:

from urllib import request
from urllib import parse
url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
headers = {
    
    
        'User-Agent':'xxxxxx',
        'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',
        'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'cookie': 'xxxxx'
}
data = {
    
    
        'first': 'true',
        'pn': '1',
        'kd': 'python'
}
req = request.Request(url,headers=headers,data=parse.urlencode(data).encode('utf-8'),method='POST')
resp = request.urlopen(req)
print(resp.read().decode('utf-8')) 

ProxyHandler处理器(代理设置)

很多网站会检测某二段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。所以我们可以设置一些代理服务器, 每隔-段时间换- - 个代理,就算IP被禁止,依然可以换个IP继续爬取。

urllib中通过ProxyHandler来设置使用代理服务器,下面代码说明如何使用自定义opener来使用代理:

from urllib import request

#没有使用代理

# url = 'http://httpbin.org/ip'
# resp = request.urlopen(url)
# print(resp.read())

#使用代理
url = 'http://httpbin.org/ip'
# 1. 使用ProxyHander,传入代理构建一个handler
handler = request.ProxyHandler({
    
    "http":"110.243.25.158:9999"})
# 2. 使用上面创建的handler构建一个opener
opener = request.build_opener(handler)
# 3 .使用opener去发送请求
resp = opener.open(url)
print(resp.read())

ProxyHandler处理器 (代理) :

1.代理的原理:在请求目的网站之前,先请求代理服务器,然后让代理服务器去请求目的

网站,代理服务器拿到目的网站的数据后,再转发给我们的代码。

2.http://httpbin.org:这个网站可以方便的查看http请求的一-些参数

3.在代码中使用代理:

*使用urllib. request .ProxyHandler", 传入一个代理,这个代理是一个字典,字典的key依赖于代理服务器能够接收的类型,一般是^http.或者https",值是“ip:port"

*使用上一步创建的handler", 以及request . build_ opener创建- -个opener"对象。

*使用上一步创建的“opener", 调用open"函数,发起请求。

常用的代理

  1. 快代理:https://www.kuaidaili.com/free/
  2. 代理云:http://www.dailiyun.com/

cookie

在网站中,http请求是无状态的。也就是说即使第一次和服务器连 接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie 的出现就是为了解决这个问题,第一-次置录后服 务器返回-些数据(cookie) 给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookde 数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie 存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB.因此使用cookie只能存储一些小量的数据。

cookie的格式:

Set-Cookie: NAME=VALUE: Expires/Max-age-DATE: Path-PATH: Dosain-DOMAIN NANE: SECURE

参数意义:

  • NAME: cookie的名字。
  • VALUE: cookie的值。
  • Expires: cookie的过期时间。
  • Path: cookie作用的路径。
  • Domain: cookie作用的域名。
  • SECURE: 是否只在https协议下起作用。

使用cookielib库和HTTPCookieProcessor模拟登录:

Cookie是指网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件,Cookie可以保持置录信息到用户下次与服务器的会话。

这里以人人网为例。人人网中,要访问某个人的主页,必须先登录才能访问,登录说白了就是要有cookie信息。那么如果我们想要用代码的方式访问,就必须要有正确的cookie信息才能访问。解决方案有两种,第-种是使用刘览器访问,然后将cookie信息复制下来,放到headers中。示例代码如下:

from urllib import request
from urllib import parse
url = "http://www.renren.com/880151247/profile"
headers = {
    
    
        'User-Agent': 'xxxxx',
        'Referer':'http://www.renren.com/880151247/profile',
        'Cookie': 'xxxxx'
}
req = request.Request(url,headers=headers)
resp = request.urlopen(req)
with open('dapeng.html','w',encoding='utf-8') as fp:
    #   如何写入文件
    #   write函数必须写入一个str的数据类型
    #   resp.read()读出来的是一个byte的数据类型
    #   str ->decode ->str
    #   str ->encode ->bytes
    fp.write(resp.read().decode('utf-8'))

但是每次在访问需要cookie的页面都要从浏览器中复制cookie比较麻烦。在Python处理Cookie, -般是通过http.cookdejar 模块和u_11ib模块的HTTPCookieProcessor处理器类-起使用。http. cookiejar模块主要作用是提供用于存储cookie的对象。
而HTTPCookieProcessor处理器主要作用是处理这些cookie对象,并构建handler对象。

http.cookiejar模块:

该模块主要的类有CookieJar, FileCookieJar. MoillaCookieJar, LWPCookieJar. 这四个类的作用分别如下:

  1. CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie.向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。

  2. FileCookieJar (flename,delayload=None ,polcy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。flename是存储cookie的文件名。delayload为True时支持延迟访问访问文件, 即只有在需要时才读取文件或在文件中存储数据。

  3. MozillaCookieJar (flename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Moilla浏览器cookies .txt兼容的FileCookieJar实例。

  4. LWPCookieJar (flename delayload=None,policy=None):从FileCookieJar派生 而来,创建与1bwww-per标准的Set-Cookie3文件格式兼容的FileCookieJar实例。

利用http .cookiejaer和request HTTPCookieProcessor登录人人网。相关示例代码如下:

from urllib import request
from urllib import parse
from http.cookiejar import CookieJar

#   1.登录
#   1.1 创建一个cookiejar对象
cookiejar = CookieJar()
#   1.2 使用cookiejar创建一个HTTPCookieProcess对象
handler = request.HTTPCookieProcessor(cookiejar)
#   1.3 使用上一步创建的handler创建一个opener
opener = request.build_opener(handler)
#   1.4 使用opener发送登录情趣(个人邮箱和密码)
headers = {
    
    
            'User-Agent': 'xxxxx',
            'Referer':'http://www.renren.com/880151247/profile'
}
data = {
    
    
    'email':"xxxxx",
    'password':"xxxxx"  //自己的密码
}
login_url = "http://www.renren.com/PLogin.do"

req = request.Request(login_url,data=parse.urlencode(data).encode('utf-8'),headers=headers )
result = opener.open(req)
#   2.访问个人主页
dapeng_url = "http://www.renren.com/880151247/profile"
# 获取个人主页信息的时候,不要新建一个opener
# 而应该使用之前的opener,因为之前的opener已经包含了登录所需的cookie信息
req = request.Request(dapeng_url,headers=headers)
resp = opener.open(req)
with open('renren.html','w',encoding='utf-8') as fp:
    fp.write(resp.read().decode('utf8'))
//把各部分弄成函数,代码更精简
from urllib import request
from urllib import parse
from http.cookiejar import CookieJar
headers = {
    
    
            'User-Agent': 'xxxxx',
            'Referer':'http://www.renren.com/880151247/profile'
    }
def get_opener():
    #   1.登录
    #   1.1 创建一个cookiejar对象
    cookiejar = CookieJar()
    #   1.2 使用cookiejar创建一个HTTPCookieProcess对象
    handler = request.HTTPCookieProcessor(cookiejar)
    #   1.3 使用上一步创建的handler创建一个opener
    opener = request.build_opener(handler)
    return opener
def login_return(opener):
    #   1.4 使用opener发送登录情趣(个人邮箱和密码)
    data = {
    
    
    'email':"xxxxx",
    'password':"xxxxx" //自己的密码
    }
    login_url = "http://www.renren.com/PLogin.do"
    req = request.Request(login_url,data=parse.urlencode(data).encode('utf-8'),headers=headers )
    result = opener.open(req)
def visit_profile(opener):
    #   2.访问个人主页
    dapeng_url = "http://www.renren.com/880151247/profile"
    # 获取个人主页信息的时候,不要新建一个opener
    # 而应该使用之前的opener,因为之前的opener已经包含了登录所需的cookie信息
    req = request.Request(dapeng_url,headers=headers)
    resp = opener.open(req)
    with open('renren.html','w',encoding='utf-8') as fp:
        fp.write(resp.read().decode('utf8'))
if __name__ == '__main__':
    opener = get_opener()
    login_return(opener)
    visit_profile(opener)

保存cookie到本地:

保存cookie到本地,可以使用cookiejar的save 方法,并且需要指定一个文件名:

//测试网址:http://httpbin.org/cookies/set?course=abc
//把cookie保存到本地
from urllib import request
from urllib import parse
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar("cookie.txt")
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
resp = opener.open("http://httpbin.org/cookies/set?course=abc")
cookiejar.save(ignore_discard=True)  //不忽略过期的cookie信息
//加载本地cookie
from urllib import request
from urllib import parse
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar("cookie.txt")
cookiejar.load(ignore_discard=True)
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
resp = opener.open("http://httpbin.org/cookies")
for cookie in cookiejar:
    print(cookie)

requests库

虽然Python的标准库中urlib模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人感觉不太好,而Requests宣传是"HTTP for Humans",说明使用更简洁方便。

发送Get请求

  1. 最简单的发送get请求就是通过requests.get 来调用:
response = requests.get("http://www.baidu.com")
  1. 添加headers和查询参数:|

如果想添加headers,可以传入headers参数来增加请求头中的headers信息。如果要将参数放在url中传递,可以利用params参数。相关示例代码如下:

import requests
kw = {
    
    'wd':'中国'}
headers = {
    
    
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
}
# params 接收一个字典或着字符中的查询参数。字典类型自动转换为url编码。不需要urlencode()
resp = requests.get("http://www.baidu.com/?",params = kw,headers = headers)
#查看响应内容,resp.text返回的是Unicode格式的数据
# print(type(resp.text))    //<class 'str'>
# print(resp.text)  //乱码
#查看响应内容,resp.content返回的字节型数据
# print(type(resp.content))   #<class 'bytes'>
# print(resp.content.decode('utf-8')) #正常
#查看完整url地址
#print(resp.url)
#查看响应头部字符编码
#print(resp.encoding)
#查看响应码
print(resp.staus_code)

发送POST请求:

  1. 最基本的POST请求可以使用post方法:
resp = requests.post('http://www.lagou.com',data=data)
  1. 传入data数据:

这时候就不要再使用urlencode进行编码了,直接传入一个字典进去就可以了。比如请求拉勾网的数据的代码:

import requests
data = {
    
    
    'first': 'true',
    'pn': '1',
    'kd': 'java'
}
headers = {
    
    
        'User-Agent':'xxxxx',
         'Referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',
         
}
resp = requests.post("https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false",data=data,headers=headers)
print(resp.text)

使用代理

使用requests添加代理也非常简单,只要在请求的方法中(比如get或者post)传递proxdes参数就可以了,示例代码如下:

import requests
url = "http://httpbin.org/get"
headers = {
    
    
"User-Agent": "xxxxx"
}
proxy = {
    
    
    'http':'180.141.90.145:53281'
}
resp = requests.get(url,proxies=proxy,headers=headers)
with open('xx.html','w',encoding='utf-8') as fp:
    fp.write(resp.text)

cookie

如果在一个响应中包含了cookle ,那么可以利用cookdes属性拿到这个返回的cookde 值:

import requests
resp = requests.get("http://www.baidu.com")
print(resp.cookies)
print(resp.cookies.get_dict())  #以字典形式返回

session:

之前使用|ur1lib库,是可以使用opener发送多个请求,多个请求之间是可以共享cookie 的。那么如果使用requests ,也要达到共享cookie的目的,那么可以使用requests库给我们提供的session对象。注意,这里的ssion不是web开发中的那个session,这个地方只是-个会话的对象而已。还是以登录人人网为例,使用requests 来实现。示例代码如下:

import requests
url = 'http://www.renren.com/PLogin.do'
data = {
    
    
    'email':'xxx',
    'password':'xxx'
}
headers = {
    
    
        'User-Agent': 'xxxxx',
        'Referer':'http://www.renren.com/880151247/profile'
}
session = requests.session()
session.post(url,headers=headers,data=data)
resp = session.get("http://www.renren.com/880151247/profile")
print(resp.content.decode('utf-8'))

处理不信任的SSL证书:

对于那些已经被信任的SSL整数的网站,比如hts://ww.baidu.com/ ,那么使用requests直接就可以正常的返回响应。示例代码

如下:

resp = requests.get("http://www.12306.cn",verify=False)
print(resp.content.decode('utf-8'))

猜你喜欢

转载自blog.csdn.net/weixin_44216796/article/details/109803894