爬虫请求
爬虫的分类
-
通用爬虫通用爬虫是搜索引擎抓取系统(百度、谷歌、搜狗等)的重要组成部分。主要是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
-
聚焦爬虫(定向爬虫):是面向特定需求的一种网络爬虫程序,他与通用爬虫的区别在于:聚焦爬虫在实施网页抓取的时候会对内容进行筛选和处理,尽量保证只抓取与需求相关的网页信息。
HTTP协议
HTTP(Hyper Transfer Protocal)协议,中文名为超文本传输协议,是一种发布和接收HTML页面的方法。服务器端口号是80
端口。
HTTPS协议,是HTTP协议的加密版本,在HTTP下加入了SSL层。服务器端口号是443
端口。
HTTP请求过程
当浏览器向服务器发送HTTP请求时,它就会发送一个Request
请求html
文件,服务器就会把Response
文件对象发送回浏览器。当浏览器在分析Response
中的html
,发现其中引用了很多如css
的其他文件,那么浏览器就会自动地再次发送Response
去获取其他文件。
URL详解
URL
是Uniform Resource Locator的简称,称为统一资源定位符。
scheme://host:port/path/?query-string=xxx#anchor
-
scheme
代表访问的协议,有http
、https
和ftp
等。 -
host
代表主机,域名。 -
post
代表端口号,浏览器默认为80
。 -
path
查找的路径。如https://www.zhihu.com/question/317729805/answer/634561449
中question/317729805/answer/634561449
就是路径。 -
query-string
查询字符串,如www.baidu.com/s?wd=python
其中wd=python
就是查询字符串。 -
anchor
网页的锚点
请求头的常见参数
User-Agent
浏览器的名称,通过爬虫请求的话默认是python
。因此,如果我们想要正常获取信息的话,就需要把这个值设置成一些浏览器的值。
Referer
表面当前这个请求时从哪个URL
发送过来的,如果不是指定的页面,那么就不做任何响应。
Cookie``HTTP
协议是无状态的,因此需要用Cookie
来做标识。如果想要访问登陆后才能访问的网站,那么就需要发送Cookie
信息。
urllib
库
urllib
库可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保持服务器返回的数据。所有和网络请求相关的方法,都被搜集到了urllib.request
模块下了。
urlopen
函数
from urllib import request
resp = request.urlopen("https://www.cnblogs.com")
print((resp.read()).decode("utf-8"))
该函数向URL
发送请求,然后返回一个叫http.client.HTTPResponse
的类文件句柄的对象。其有read
、readline
、readlines
和getcode
等方法。
urlretrieve
该函数与urlopen
函数类似,不过它可以把文件下载下来。
from urllib import request
request.urlretrieve("https://www.cnblogs.com","blog.html")
urlencode
函数
当浏览器向服务器发送请求时,会自动的把中文或者其他特殊字符进行编码。如果我们用代码来发送请求就需要用urlencode
函数来进行编码,它可以把字典数据转换成URL
编码的数据。
from urllib import parse
data = {
"name":"袁铭",
"hometown":"眉山"
}
qs = parse.urlencode(data)
print(qs)
"""
name=%E8%A2%81%E9%93%AD&hometown=%E7%9C%89%E5%B1%B1
"""
parse_qs
函数
利用parse_qs
函数可以对url
参数进行解码。
from urllib import parse
qs = "name=%E8%A2%81%E9%93%AD&hometown=%E7%9C%89%E5%B1%B1"
data = parse.parse_qs(qs)
print(data)
'''
{'name': ['袁铭'], 'hometown': ['眉山']}
'''
urlparse
和urlsplit
函数
urlparse
函数和urlsplit
函数可以对url
中的各个部分进行分割。其中urlparse
会生成一个SplitResult
对象,而urlparse
会生成一个ParseResult
对象,且比SplitResult
多一个params
属性。
##urlparse()函数
from urllib import request,parse
url = "https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc"
res = parse.urlparse(url)
print(res)
"""
result:
ParseResult(scheme='https', netloc='baijiahao.baidu.com', path='/s', params='', query='id=1629848884406903523&wfr=spider&for=pc', fragment='')
"""
##urlsplit()函数
from urllib import request,parse
url = "https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc"
res = parse.urlsplit(url)
print(res)
"""
result:
SplitResult(scheme='https', netloc='baijiahao.baidu.com', path='/s', query='id=1629848884406903523&wfr=spider&for=pc', fragment='')
"""
params
属性
params
属性用的比较少,url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'
中,hello
就是params
属性。比如:
from urllib import request,parse
url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'
res = parse.urlparse(url)
print(res.params)
"""
result:
hello
"""
request.Request
类
在request.Request
类里面可以添加一些请求头。
from urllib import request
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = request.Request("https://baijiahao.baidu.com/s?id=1629848884406903523&wfr=spider&for=pc",headers=headers)
res = request.urlopen(resp)
print(res.read().decode("utf-8"))
ProxyHandler
处理器(代理设置)
通过这个设置可以防止因为一个IP
地址多次访问一个网站而被禁止访问的现象。
from urllib import request
handler = request.ProxyHandler({"http":"116.209.56.20"})
opener = request.build_opener(handler)
req = request.Request("https://httpbin.org/ip")
res = opener.open(req)
print(res.read())
Cookie
及其在python
爬虫中应用
http
请求是无状态的,即第一次和服务器连接登陆后,第二次依然需要登陆,这样我们就需要Cookie
了。Cookie
是指网站服务器为了辨别用户身份和进行Session
跟踪,而储存在用户浏览器上的文本文件,Cookie
可以保持登录信息到用户下次与服务器的会话。一般的浏览器只会存储4kb
大小的Cookie
信息。
Cookie
格式
Set-Cookie: NAME=VALUE;Expires/Max-age=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
-
NAME
:Cookie
的名字 -
VALUE
:Cookie
的值 -
Expires
:Cookie
的过期时间 -
Path
:Cookie
的作用路径 -
Domain
:Cookie
作用的域名 -
SECURE
:是否只在https
协议下起作用
HTTPCookieProcessor
模拟登陆
自己把相关Cookie
信息复制下来的方法
from urllib import request
header = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
"Cookie":'''_zap=7e00df33-291a-444c-bbd5-a577341759a3; d_c0="AJAneIGlfA6PTmd1grAygRROsv0NXxdm5CY=|1541663054"; _xsrf=0drRAYeKwmdbZ11UYOF8cJy9ZRT1cMec; z_c0="2|1:0|10:1543657267|4:z_c0|92:Mi4xSHFOUEJnQUFBQUFBa0NkNGdhVjhEaVlBQUFCZ0FsVk5NNlh2WEFBckU4ZE5mUjRPdHdzTFpiMS1uXzRHTUFRdWVn|b16b34b217ea382b1094e15ca41eac496c65ae276e30a492b77ab06b4824561d"; __gads=ID=72e38c174d9d49c9:T=1547028103:S=ALNI_Maqfn0xeXVKXQ3l2ty6KhIGzTq6wg; tst=r; __utma=51854390.323199518.1550992135.1550992135.1550992135.1; __utmz=51854390.1550992135.1.1.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmv=51854390.100--|2=registration_date=20171026=1^3=entry_date=20171026=1; q_c1=69c989b9edc24cc991722eaef9f39ec0|1552728574000|1541663056000'''
}
resq = request.Request("https://www.zhihu.com/",headers=header)
res = request.urlopen(resq)
with open("pachong.html","wb") as f:
f.write(res.read())
模拟登陆与http.cookiejar
模块
该模块具有以下的几个类:
CookieJar
:管理、存储和向外传输HTTP Cookie
FileCookieJar(filename,delayload=None,policy=None)
:该模块是从CookieJar
派生来的,可以创建FileCookieJar
实例,并把相关信息存储到文件里。filename
:存储Cookie
的文件名delayload
:该属性为True
时,支持延迟访问文件
MozillaCookieJar(filename,delayload=None,policy=None)
:该模块从FileCookieJar
派生而来,创建与Mozilla浏览器cookies.txt
兼容的FileCookieJar
实例LWPCookieJar(filename,delayload=None,policy=None)
:也是从FileCookieJar
派生而来,创建与libwww-perl
标准的Set-Cookie3
文件格式兼容的FileCookieJar
实例
小实例
from urllib import parse,request
from http.cookiejar import CookieJar
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
cookiejar = CookieJar()
handle = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handle)
data = {
"username":"***********",
"password":"***********"
} ##存储登陆账号和密码,对应的参数可以在html源代码中查找
data = parse.urlencode(data).encode("utf-8")
login_url = "https://www.zhihu.com/signup?next=%2F" ##使用登陆页面的url
req = request.Request(login_url,headers=headers,data=data)
opener.open(req) ##登陆并获得Cookie
url = "https://www.zhihu.com/question/60371302/answer/632445421"
req = request.Request(url,headers=headers)
resp = opener.open(req)
with open("zhihu.html","wb") as f:
f.write(resp.read())
Cookie
本地化和本地加载
from urllib import request from http.cookiejar import MozillaCookieJar cookiejar = MozillaCookieJar("cookie.txt") handler = request.HTTPCookieProcessor(cookiejar) opener = request.build_opener(handler) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36' } req = request.Request('http://httpbin.org/cookies',headers=headers) resp = opener.open(req) print(resp.read()) cookiejar.save(ignore_discard=True,ignore_expires=True)##如果断开Cookie就消失的话,就应该设置`save()`函数里面的参数
from urllib import request from http.cookiejar import MozillaCookieJar cookiejar = MozillaCookieJar("cookie.txt") cookiejar.load(ignore_expires=True,ignore_discard=True) ##加载 handler = request.HTTPCookieProcessor(cookiejar) opener = request.build_opener(handler) headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) >AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 >Safari/537.36'} req = request.Request('http://httpbin.org/cookies',headers=headers) resp = opener.open(req) print(resp.read())
requests
库
get
及其实例化的属性
params
:接受一个字典或者字符串的查询参数,其不需要urlencode()
就可以转换成url
编码,如requests.get("https://www.baidu.com/s",kw,headers=heads)
,其中kw={"wd":"python}
,它会自动地把url
拼接为https://www.baidu.com/s?wd=pyhon
text
:返回Unicode格式的内容content
:返回字节流数据,其会自动帮你解码,但是容易出错url
:返回其完整的url地址encoding
:查看响应头部字符编码status_code
:查看响应码
小实例
import requests
kw = {
"wd":"python"
}
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = requests.get("http://www.baidu.com/s",params = kw,headers=headers)
with open("res.html","w",encoding="utf-8") as f:
f.write(resp.content.decode("utf-8"))
post
及其小实例
import requests url = "https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false&isSchoolJob=0" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36', 'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' } data = { 'first': 'true', 'pn': 1, 'kd': 'python' } resp = requests.post(url,headers=headers,data=data) # 如果是json数据,直接可以调用json方法 print(resp.json())
使用代理
import requests
url = "http://httpbin.org/ip"
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
proxy = {
"http":"182.34.37.198:9999"
}
resp = requests.get(url,headers=headers,proxies=proxy) ##直接传入get()函数里面
print(resp)
Cookie
的获取
import requests
url = "https://www.zhihu.com/signup?next=%2F"
data = {
"username":"15244847273",
"password":"GNIM@yuan#88"
}
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
resp = requests.get(url)
c_s = resp.cookies ##调用cookie这个属性来获得cookie值
print(c_s.get_dict()) ##get_dict()函数会把产生的对象返回成字典的形式
Session
利用该类可以建立一个会话
import requests
url = "https://www.zhihu.com/signup?next=%2F"
data = {
"username":"***********",
"password":"***********"
}
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
}
session = requests.Session()
session.post(url,data=data,headers=headers)
reps = session.get("https://www.zhihu.com/question/317115184/answer/631075262")
print(reps.text)
不被信任的SSL证书处理
resp = requests.get("URL",verify=False)
在get()
函数里面加入verify=False
参数就可以处理了