从上往下:
应用层:为用户的应用程序提供网络服务的(http,https,ftp。。。。。)
表示层:负责端到端的数据信息可以被另一个主机所理解和识别,并且按照一定的格式将信息传递到会话层
会话层:管理主机之间的会话进程,负责建立,管理,和终止会话进程
传输层:进行数据传输(TCP UDP)
网络层: 路由器
数据链路层:网桥 交换机
物理层 : 网线 网卡 集线器 中继器
200 :请求成功
301 : 永久重定向
302 : 临时重定向
401 : 未授权
403 : 服务器拒绝访问
404 : 页面丢失
405 : 请求方式不对
408 : 请求超时
500 : 服务器错误
503 : 服务器不可用
会携带请求头:
#目标url
url = 'http://www.baidu.com/'
# request.urlopen():使用urlopen方法模拟浏览器发起请求
"""
url, 请求的目标url地址
data=None,默认情况为None,表示发起的是一个get请求,不为None,则发起的是一个post请求
timeout=,设置请求的超时时间
cafile=None, 设置证书
capath=None, 设置证书路径
cadefault=False, 是否要使用默认证书(默认为False)
context=None:是一个ssl值,表示忽略ssl认证
"""
#是一个ssl值,表示忽略ssl认证(如果请求出现了ssl证书认证错误,
# 我们就需要设置ssl._create_unverified_context(),忽略证书认证)
content = ssl._create_unverified_context()
response = request.urlopen(url,timeout=10,content=content)
#从response响应结果中获取参数
#状态码
code = response.status
print(code)
#获取页面源码的二进制数据
b_html = response.read()
print(type(b_html),len(b_html))
#获取响应的响应头部(Response Headers)
res_headers = response.getheaders()
print(res_headers)
#获取响应头中指定参数的值
cookie_data = response.getheader('Set-Cookie')
print(cookie_data)
#reason返回一个响应结果的原因
reason = response.reason
print(reason)
#将获取到的二进制数据,转换为字符串decode
str_html = b_html.decode('utf-8')
print(type(str_html))
with open('b_baidu.page.html','w') as file:
# file.write(b_html)
file.write(str_html)
#如果请求要携带请求头
#需要先构建一个request对象
"""
url:发起请求的url地址
data=None, 默认情况为None,表示发起的是一个get请求,不为None,则发起的是一个post请求
headers={},设置请求头(headers对应的数据类型是一个字典)
origin_req_host=None, (指定发起请求的域)
unverifiable=False,忽略SSL认证
method=None:指定发起请求的方式
"""
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
req = request.Request(url,headers=req_header)
#根据构建的req请求对象发起请求
response = request.urlopen(req)
response.status
. :表示匹配除了换行符之外的任意字符
\ :转义字符
[a-z] : 匹配a-z里面的任意一个字符
's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
\d: 匹配数字 -> [0-9]
\D: 匹配非数字 [^\d]
\s: 匹配空白字符(空格,\n,\t...)
\S: 匹配非空白字符
\w: 匹配单词字符 [A-Za-z0-9_]
\W: 匹配非单子字符
^:匹配以...开头
$:匹配以....结尾
():分组
|:或
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
'(?P...)' 分组匹配 re.search("(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{4})" ,
"371481199306143242").groupdict("city")
结果{'province': '3714', 'city': '81', 'birthday': '1993'}
多字符匹配
*:匹配*前面的字符任意次数
+ : 匹配+号前面的字符至少1次
?: 匹配?前面的字符0次或1次
{m}:匹配{m}前面的字符m次
{m,n}:匹配{m,n}前面的字符m~n次
非贪婪匹配
*?
+?
??
{m,n}?
原字符
r : 原来的字符串怎么写,现在就怎么写
例如 url(r'^admin/', admin.site.urls)
import re
#把正则表达式构建为一个pattern对象
sub_str = 'abcdefabcd'
pattern = re.compile('b')
#从字符串的起始位置开始匹配,开头就必须符合正则规则,
# 如果匹配到结果了返回结果,如果匹配不到返回None,单次匹配
result = re.match(pattern,sub_str)
print(type(result))
if result:
print(result.group())
#在整个字符串中进行匹配,同样是单次匹配,匹配到结果立即返回
#匹配不到则返回None
result = re.search(pattern,sub_str)
print(result.group())
# 再整个字符串中进行匹配,匹配出所有符合正则规则的结果,
# 以列表的形式返回
result = re.findall(pattern,sub_str)
print(result)
#再整个字符串中进行匹配,匹配出所有符合正则规则的结果,
#但是返回的是一个迭代器
result = re.finditer(pattern,sub_str)
#
print(type(result))
for note in result:
#
print(type(note))
print(note.group())
#替换re.sub()
url = 'http://www.baidu.com/s?kw=aaa&pn=20'
# pattern, \正则规则
# repl, \要替换的字符串
# string,原始字符串
pattern = re.compile('pn=\d+')
result = re.sub(pattern,'pn=30',url)
print(result)
#分割re.split()
pattern = re.compile('[=:&]')
#pattern, string
result = re.split(pattern,url)
print(result)
sub_html = """
"""
#re.S让点可以匹配包括换行符的任意字符
pattern = re.compile(
'' +
'.*?' ,re.S
)
result = re.findall(pattern,sub_html)
print(result)
from urllib import request
# 目标url:
# https://www.douban.com/people/175417123/
url = 'https://www.douban.com/people/175417123/'
# 设置请求头
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Cookie': 'bid=a5HEJxBlOLY; douban-fav-remind=1; ll="108288"; _vwo_uuid_v2=D4EC41D965B5FF84E814BF48AE34386A5|f6047e628a6acc98722e3100dfbc399c; __yadk_uid=KpfeK1cgib5IWMKWvG66MnJMbonYvDZa; _ga=GA1.2.36315712.1531837787; douban-profile-remind=1; push_doumail_num=0; push_noty_num=0; __utmv=30149280.17541; _gid=GA1.2.2070226630.1545227516; ps=y; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1545292749%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DqpgHwc2FYGfOrGzt4yK3ZwwbraVm_oED80whnivpFaC3kA5IvGnUfQ9FSRZBOEVh%26wd%3D%26eqid%3D85ed620e000397aa000000065c1b4bc8%22%5D; _pk_ses.100001.8cb4=*; __utma=30149280.36315712.1531837787.1545227511.1545292752.48; __utmc=30149280; __utmz=30149280.1545292752.48.37.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmt=1; dbcl2="175417123:yY3DyEelGJE"; ck=FxtM; ap_v=0,6.0; _pk_id.100001.8cb4=7521abce5497fc2c.1531837784.39.1545292778.1545228853.; __utmb=30149280.7.10.1545292752',
}
req = request.Request(url=url,headers=req_header)
response = request.urlopen(req)
if response.status == 200:
with open('douban.html','w') as file:
file.write(response.read().decode('utf-8'))
#使用cookiejar的目的:管理cookie,保存cookie值,
#一旦存储cookie之后,下一次发起请求的时候就会携带cookie
#cookie是保存在内存里面的,最后会进行垃圾回收
from urllib import request,parse
from http.cookiejar import CookieJar
#创建cookiejar对象,目的如上
cookie_jar = CookieJar()
#HTTPCookieProcessor创建handle处理器,管理cookiejar
handler = request.HTTPCookieProcessor(cookie_jar)
#自定义opener
opener = request.build_opener(handler)
#分析发现
# https://www.douban.com/accounts/login
# 没有验证码的情况
# source: index_nav
# form_email: 18518753265
# form_password: ljh12345678
#有验证码的情况
# source: index_nav
# form_email: 18518753265
# form_password: ljh12345678
# captcha-solution: blade
# captcha-id: 5IBtw5wm2riyrIrnV3utwUPt:en
url = 'https://www.douban.com/accounts/login'
form_data = {
'source': 'index_nav',
'form_email': '18518753265',
'form_password': 'ljh12345678',
'captcha-solution': 'noise',
'captcha-id': 'waNQIJD6TkMaF4M51PFg5kYh:en'
}
form_data = parse.urlencode(form_data).encode('utf-8')
#设置请求头
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
#够建一个request对象
req = request.Request(url,headers=req_header,data=form_data)
#发起请求
response = opener.open(req)
#登录成功后访问个人主页,能够成功获取到个人主页信息,说明确实保存了cookie
#并且在一下次发起请求的时候携带了cookie
url = 'https://www.douban.com/people/175417123/'
req = request.Request(url,headers=req_header)
response = opener.open(req)
if response.status == 200:
with open('douban.html','w') as file:
file.write(response.read().decode('utf-8'))
# urllib.error:在发起请求的过程中,可能会因为各种情况
# 导致请求出现异常,因而导致代码崩溃,所以我们悬疑处理这些异常的请求
from urllib import error,request
# error.URLError
def check_urlerror():
"""
1.没有网络
2.服务器连接失败
3.找不到指定服务器
:return:
"""
url = 'http://www.baidu.com/'
try:
response = request.urlopen(url,timeout=0.01)
print(response.status)
except error.URLError as err:
#[Errno -2] Name or service not known(未知服务器)
#timed out:请求超时
#[Errno -3] Temporary failure in name resolution(没网)
print(err.reason)
# check_urlerror()
# error.HTTPError是URLError的子类
def check_httperror():
url = 'https://www.qidian.com/all/nsacnscn.htm'
try:
response = request.urlopen(url)
print(response.status)
except error.HTTPError as err:
#HTTPError的三个属性
#状态码
print(err.code)
#返回错误的原因
print(err.reason)
#返回响应头
print(err.headers)
except error.URLError as err:
print(err.reason)
check_httperror()
#urllib的parse模块主要是实现url的解析,合并,编码,解码
from urllib import parse
#parse.urlparse实现了url的识别和分段
url = 'https://www.1712B.com/daxuesheng?name=zhangsan#123'
"""
url,:要解析和才分的url
scheme='':设置协议,只有在url没有协议的情况下才会生效
allow_fragments=True:是否忽略锚点,默认为True表示不忽略
"""
result = parse.urlparse(url)
"""
(scheme='https'(协议), netloc='www.1712B.com'(域),
path='/daxuesheng'(路径), params=''(可选参数),
query='name=zhangsan'(查询参数), fragment='123'(锚点))
"""
print(result)
#取出才分后的某一个参数
print(result.scheme)
#parse.urlunparse可以实现url的组合
data = [sub_str for sub_str in result]
print('-----',data)
full_url = parse.urlunparse(data)
print(full_url)
#parse.uurlrljoin需要传递一个基类url,根据基类将某一个不完整的url拼接完整
sub_url = '/p/123456'
base_url = 'https://www.1712B.com/daxuesheng?name=zhangsan#123'
full_url = parse.urljoin(base_url,sub_url)
print('urljoin',full_url)
#parse.urlencode将字典类型的参数,序列化为url的编码格式的字符串
parmars = {
'name':'张三',
'class':'1712B',
}
result = parse.urlencode(parmars)
print('urlencode',result)
#parse.parse_qs反序列化,将url编码格式的字符串,转为字典类型
result = parse.parse_qs(result)
print('parse_qs',result)
#parse.quote可以将中文字符,转为url编码格式
kw = '摸摸摸'
result = parse.quote(kw)
print('quote',result)
#将url编码进行解码
result = parse.unquote(result)
print('unquote',result)
# 最最常用的urljoin,urlencode两个方法
# urllib下使用代理
# http/https代理
# 一定是一个高匿代理理
# 隐藏真实ip
from urllib import request
#自定义ProxyHandler的目的是为了设置代理,使用代理发起请求
#proxies:对应的是一个字典
# 代理有免费代理(西刺,快代理.....)
# 和收费代理 (西刺,快代理.....,阿布云....)
# proxies = {
# 'http':'118.187.58.34:53281',
# 'https':'124.235.180.121:80',
# }
#独享代理,需要账号密码做验证的
proxies = {
'http':'http://2295808193:[email protected]:16818',
'https':'https://2295808193:[email protected]:16818'
}
handler = request.ProxyHandler(proxies=proxies)
#自定义opener
opener = request.build_opener(handler)
#url地址
#https://httpbin.org/get
url = 'http://httpbin.org/get'
response = opener.open(url)
print(response.status)
print(response.read().decode('utf-8'))
#pip3 install requests
#requests模块:是对urllib的封装,可以实现urllib的所有功能
#并且api调用更加简单方便
import requests
# url = 'http://www.baidu.com/'
url = 'http://www.sina.com'
# url, :要请求的目标url
# params:get请求后面要拼接的参数
"""
:param method: 要发起的是什么类型的请求.
:param url: 要请求的目标url
:param params: get请求后面要拼接的参数
:param data: Dictionary, post请求的表单数据
:param json: 传递json数据跟上面的data效果类似
:param headers: (optional) Dictionary 请求头
:param cookies: (optional) Dict or CookieJar object (设置cookies信息模拟用户请求)
:param files: 上传文件
:param auth: 网站需要验证的信息(账号和密码)
:param timeout: 设置请求的超时时间
:param allow_redirects: bool,是否允许重定向
:param proxies: (optional) Dictionary (设置代理)
:param verify: Defaults to ``True``.(忽略证书认证,默认为True表示不忽略)
"""
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
parmars = {
'wd':'豆瓣'
}
# response = requests.get(url,params=parmars,headers=req_header)
response = requests.get(url,headers=req_header)
response.encoding='utf-8'
#从响应结果中获取的信息
#(这里得到的是解码后的字符串)
html = response.text
"""
#如果使用response.text出现了乱码
方式一
#response.content.decode('')
方式二
response.encoding=''设置编码类型
"""
#获取bytes类型的数据
b_html = response.content
#获取状态码
code = response.status_code
#获取响应头
response_headers = response.headers
#请求头
req_headers = response.request.headers
#获取当前请求的url地址
current_url = response.url
#response.json():可以将json字符串转为python数据类型
print(code)
print(html)
import requests
#url, 目标url
# data=None,:post请求要上传的表单数据
url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
form_data = {
'first': 'true',
'pn': 1,
'kd': 'python',
}
#设置请求头
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=',
}
response = requests.post(url,data=form_data,headers=req_header)
print(response.status_code)
print(response.text)
#可以吧将返回的json字符串转为python数据类型
data = response.json()
print(type(data))
#web客户端验证
import requests
#设置认证信息
auth = ('username','password')
url = 'http://192.168.1.110'
response = requests.get(url,auth=auth)
print(response.status_code)
import requests
#分析发现
# https://www.douban.com/accounts/login
# 没有验证码的情况
# source: index_nav
# form_email: 18518753265
# form_password: ljh12345678
#有验证码的情况
# source: index_nav
# form_email: 18518753265
# form_password: ljh12345678
# captcha-solution: blade
# captcha-id: 5IBtw5wm2riyrIrnV3utwUPt:en
url = 'https://www.douban.com/accounts/login'
form_data = {
'source': 'index_nav',
'form_email': '18518753265',
'form_password': 'ljh12345678',
'captcha-solution': 'violent',
'captcha-id': 'AuKNJ1FIktyrmpljJ6WAzXo3:en'
}
#设置请求头
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
#发起请求
response = requests.post(url,headers=req_header,data=form_data)
#使用response.cookies获取cookies信息
print('模拟登录后的cookies信息',response.cookies)
print(type(response.cookies))
print(response.headers)
with open('douban.html','w') as file:
file.write(response.text)
#requests.utils.cookiejar_from_dict():将字典转为cookiejar
#requests.utils.dict_from_cookiejar():将cookiejar转为字典
cookies_dict = requests.utils.dict_from_cookiejar(response.cookies)
print(cookies_dict)
#登录成功后访问个人主页,能够成功获取到个人主页信息,说明确实保存了cookie
#并且在一下次发起请求的时候携带了cookie
url = 'https://www.douban.com/people/175417123/'
#设置cookies参数,模拟用户发起请求
response = requests.get(url,headers=req_header,cookies=cookies_dict)
if response.status_code == 200:
with open('douban1.html','w') as file:
file.write(response.text)
import requests
proxies = {
'http':'219.238.186.188:8118',
'https':'222.76.204.110:808',
'https':'https://username:password@ip:port',
'http':'http://username:password@ip:port'
}
url = 'https://httpbin.org/get'
response = requests.get(url,proxies=proxies,timeout=10)
print(response.text)
#requests.session():维持会话,可以让我们在跨请求时保存某些参数
import requests
#实例化session
session = requests.session()
#目标url
url = 'https://www.douban.com/accounts/login'
form_data = {
'source': 'index_nav',
'form_email': '18518753265',
'form_password': 'ljh12345678',
'captcha-solution': 'stamp',
'captcha-id': 'b3dssX515MsmNaklBX8uh5Ab:en'
}
#设置请求头
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
#使用session发起请求
response = session.post(url,headers=req_header,data=form_data)
if response.status_code == 200:
#访问个人主页:
url = 'https://www.douban.com/people/175417123/'
response = session.get(url,headers = req_header)
if response.status_code == 200:
with open('douban3.html','w') as file:
file.write(response.text)
xpath:可以在xml中查找信息,对xml文档中元素进行遍历和属性的提取
xml:被设计的目的是为了传输数据,结构和html非常相识,是一种标记语言
nodename 选取此节点的所有子节点
/ 从根节点开始查找
// 匹配节点,不考虑节点的位置
. 选取当前节点
.. 选取当前节点的父节点
a/@href 取标签的数据
a/text() 取标签的文本
a[@class="123"] 根据class属性寻找标签
a[@id="123"] 根据id属性寻找标签
a[@id="123"][last()] 取最后一个id为123的a标签
a[@id="123"][postion() < 2] 取id为123的前两个a标签
参考简书:https://www.jianshu.com/p/70d064d843e6