目录结构
一、urllib库的应用
1. Python爬虫入门案例
2. 自定义请求
3. 伪装浏览器原理
1)单个User-Agent爬虫-案例
2)多个User-Agent爬虫-案例
4. 自定义opener
5. 使用代理IP
二、Python爬虫-实践案例
1. 处理GET请求
2. 网页翻页下载爬虫-案例
3. 处理POST请求案例:实现词语中英文翻译
三、异常处理 & cookie模拟登录
1. 异常处理
2. cookie模拟登录
一、urllib库的应用
1. Python爬虫入门案例
案例:利用Python请求获取指定url的响应数据(获取信息),然后对获取的数据进行正则匹配以提取指定的内容(清洗信息)
crawler001.py
from urllib import request
import re
# 获取信息
# 确定爬虫的对象url
url=r"http://www.sogou.com"
# 发送请求,获取响应信息
data=request.urlopen(url).read()
data=data.decode() # 解码:bytes转字符串,展示中文
# 清洗信息
# 定义正则,匹配title标签中任意长度的任意字符
pat="<title>(.*?)</title>"
data=re.findall(pat,data) # 在响应数据中匹配符合正则的字符串
print(data)
清洗数据之前,所获取的响应数据为:
清洗数据之后,提取的信息为:
2. 自定义请求
crawler002.py
from urllib import request
import re
# 获取信息
url=r"http://www.sogou.com"
# 创建自定义请求对象(可封装url、User-Agent...)
rq=request.Request(url)
# 发送请求,获取响应信息
data=request.urlopen(rq).read()
data=data.decode()
# 清洗信息
pat="<title>(.*?)</title>"
data=re.findall(pat,data)
print(data[0])
备注说明:
crawler001.py 是直接在urlopen()中放入url,此时只封装了url
crawler002.py 通过自己创建自定义对象(rq),可封装url、User-Agent等信息(应对反爬虫机制),不限于只能封装url
3. 伪装浏览器原理
反爬虫机制:
① 通过判断是否使用浏览器访问,若是则通过访问,若不是则拦截访问
② 通过使用与真实浏览器一致的User-Agent信息,伪装为浏览器进行访问;同一个浏览器,不同请求对应的User-Agent信息是一致的
③ 多线程实现多次循环爬取时,若只采用同一个User-Agent,很可能被拦截访问,此时每次循环时需要从众多不同的User-Agent中随机获取使用
传送门:
常用浏览器(PC,移动) user-agent
手机UserAgent库
1)单个User-Agent爬虫-案例
crawler003.py
from urllib import request
import re
# 获取信息
url=r"http://www.sogou.com"
# 创建header字典(构造浏览器中的Request Headers)
header={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
}
# 创建自定义请求对象(可封装url、User-Agent...)
rq=request.Request(url,headers=header)
# 发送请求,获取响应信息
data=request.urlopen(rq).read()
data=data.decode()
# 清洗信息
pat="<title>(.*?)</title>"
data=re.findall(pat,data)
print(data[0])
2)多个User-Agent爬虫-案例
crawler004.py
from urllib import request
import re
import random
# 获取信息
url=r"http://www.sogou.com"
agent1="User-Agent,Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
agent2="User-Agent, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
agent3="User-Agent,Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11"
agent4="User-Agent, MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
agent5="Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36"
agent6="Mozilla/5.0 (Linux; Android 5.1.1; vivo X6S A Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044207 Mobile Safari/537.36 MicroMessenger/6.7.3.1340(0x26070332) NetType/4G Language/zh_CN Process/tools"
ls=[agent1,agent2,agent3,agent4,agent5,agent6]
agent=random.choice(ls)
print(agent)
# 创建header字典(构造浏览器中的Request Headers)
header={"User-Agent":agent}
# 创建自定义请求对象(可封装url、User-Agent...)
rq=request.Request(url,headers=header)
# 发送请求,获取响应信息
data=request.urlopen(rq).read()
data=data.decode()
# 清洗信息
pat="<title>(.*?)</title>"
data=re.findall(pat,data)
print(data[0])
4. 自定义opener
其前使用的urlopen是一个特殊的opener(模块构建好的对象),但urlopen()方法不支持代理、cookie等高级功能。为支持此类功能,通过request.build_opener()
方法创建自定义opener对象;使用自定义的opener对象,调用open()方法发送请求。
若程序里所有请求都使用自定义的opener,则可使用request.install_opener()
将自定义的opener 对象定义为全局opener,当调用urlopen,都将使用这个opener。
opener.py
from urllib import request
# 构建HTTP处理器对象(专门处理请求的对象)
http_hander=request.HTTPHandler()
# 创建自定义的opener对象
opener=request.build_opener(http_hander)
# 创建自定义请求对象
url="http://www.sogou.com"
rq=request.Request(url)
# 发送请求,获取响应
rp=opener.open(rq).read().decode()
print(rp)
将opener对象设置为全局对象,当使用urlopen时也会调用opener对象,如下:
global-opener.py
from urllib import request
# 构建HTTP处理器对象(专门处理请求的对象)
http_hander=request.HTTPHandler()
# 创建自定义的opener对象
opener=request.build_opener(http_hander)
# 创建自定义请求对象
url="http://www.sogou.com"
rq=request.Request(url)
# 发送请求,获取响应
# rp=opener.open(rq).read().decode()
# 将自定义opener设置为全局对象
request.install_opener(opener)
# 此时使用urlopen也会调用opener对象
rp=request.urlopen(rq).read().decode()
print(rp)
5. 使用代理IP
反爬虫方式1:使用User-Agent,伪装成浏览器发送请求
反爬虫方式2:判断请求来源的IP地址,使用代理IP
传送门:西刺免费代理IP
proxy.py
from urllib import request
import random
# 代理IP组成的列表
proxylist=[
{"http":"221.10.159.234:1337"},
{"http":"61.189.242.243:55484"},
{"http":"112.85.169.8:9999"},
{"http":"114.119.116.92:61066"},
{"http":"110.52.235.65:9999"},
{"http":"27.43.189.219:9999"}
]
# 从以上IP列表中随机取出1个IP
proxy=random.choice(proxylist)
print(proxy)
# 构建代理处理器对象
proxyHandler=request.ProxyHandler(proxy)
# 创建自定义opener对象
opener=request.build_opener(proxyHandler)
# 创建请求对象
url="http://www.sogou.com"
rq=request.Request(url)
# 发送请求,获取响应
rp=opener.open(rq).read().decode()
print(rp)
二、Python爬虫-实践案例
1. 处理GET请求
get.py
import urllib
from urllib import request
# http://www.sogou.com/web?query=%E6%B5%8B%E8%AF%95
# 分离url中的中文参数项
query={"query":"测试"}
url_0="http://www.sogou.com/web?"
# 构造url的参数值编码;parse解析url
q=urllib.parse.urlencode(query)
print(q)
url=url_0+q # 拼接为完整的url请求链接
# 创建请求对象
rq=request.Request(url)
# 发送请求,获取响应
rp=request.urlopen(rq).read().decode()
print(rp)
2. 网页翻页下载爬虫-案例
案例目标:根据用户输入的关键词,进入对应公众号搜索结果页面,从指定页码范围下载html文件存储到本地
分析页码的规律:
第1页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=1&ie=utf8
第2页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=2&ie=utf8
第3页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=3&ie=utf8
第4页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=4&ie=utf8
页码规律:page=页码
web-page-store.py
from urllib import request
import urllib
header={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
}
# 方法1:发送url请求,从服务器获取响应文件(爬取网页)
def loadPage(fullurl,filename):
print("正在下载:",filename)
rq=request.Request(fullurl,headers=header)
rp=request.urlopen(rq).read()
return rp
# 方法2:将HTML内容写入本地保存
def writePage(html,filename):
print("正在保存:",filename)
with open(filename,"wb") as f:
f.write(html)
print("-----------")
# 方法3:处理指定页码范围的页面的url(调用<方法1+方法2>)
def storeData(url,start,end):
for i in range(start,end+1):
page=i
fullurl=url+"&page="+str(page) # 每次请求的完整url
# 每次请求后保存的文件名
filename=r"D:\CI_Env\Python_Test\file\第"+str(page)+"页.html"
html=loadPage(fullurl,filename) # 调用爬虫,爬取网页
writePage(html,filename) # 将获取到的html网页内容写入本地保存
# 主函数:通过程序入口控制代码执行(调用方法3)
if __name__ == '__main__':
query=input("请输入公众号关键词:")
start=int(input("请输入起始页码:"))
end=int(input("请输入终止页码:"))
url="http://weixin.sogou.com/weixin?"
para=urllib.parse.urlencode({"query":query}) # 解析参数取值
url=url+para
storeData(url,start,end) # 调用执行处理指定页码的url
执行结果:
3. 处理POST请求案例:实现词语中英文翻译
案例目标:根据用户输入的词语(中文or英文),实现中英文互译
原始url:http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
调整url:http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule
请求方式:POST
代码实现:
yd-fanyi.py
from urllib import request
import urllib
import re
header={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
}
url="http://fanyi.youdao.com/translate?smartresult:dict&smartresult:rule"
words=input("翻译词语:")
# POST请求需要提交的参数(表单数据为字典类型)
formdata={
"i":words,
"from":"AUTO",
"to":"AUTO",
"smartresult":"dict",
"client":"fanyideskweb",
"salt":"15535312968212",
"sign":"d6bd41d13ab6467bec455ff06c356b33",
"ts":"1553531296821",
"bv":"e2a78ed30c66e16a857c5b6486a1d326",
"doctype":"json",
"version":"2.1",
"keyfrom":"fanyi.web",
"action":"FY_BY_REALTlME",
"typoResult":"false"
}
# 经过urlencode转码,然后用utf-8进行编码
data=urllib.parse.urlencode(formdata).encode(encoding='utf-8')
# 创建POST请求对象
req=request.Request(url,data=data,headers=header)
# 发送请求,获取响应数据
resp=request.urlopen(req).read().decode()
# 定义正则,提取翻译的内容(此时为list类型)
pat=r'"tgt":"(.*?)"'
result=re.findall(pat,resp)
# 从列表中获取翻译的有效内容
print("翻译结果:",result[0])
执行结果:
三、异常处理 & cookie模拟登录
1. 异常处理
爬虫过程中请求次数较多的场景,有可能某些请求可正常执行,某些请求异常。当请求出现异常时,为了不影响后续请求能够继续执行,需要引入异常处理机制(如:Try/Except)
exception1.py
from urllib import request
list1=[
"http://www.baidu.com",
"http://www.sogou.com",
"http://abc.123.xyz",
"http://cn.bing.com",
"http://www.yahoo.com"
]
i=0
for url in list1:
i=i+1
request.urlopen(url)
print("完成请求",i)
未对异常处理时,执行结果:
exception2.py
from urllib import request
list1=[
"http://www.baidu.com",
"http://www.sogou.com",
"http://abc.123.xyz",
"http://cn.bing.com",
"http://www.yahoo.com"
]
i=0
for url in list1:
i=i+1
try:
request.urlopen(url)
print("完成请求",i)
except Exception as e:
print(e)
处理过异常,执行结果:
2. cookie模拟登录
cookie常用作保持登录状态。若登录成功,则会出现提示登录的用户名:
cookie.py
from urllib import request
import re
url="http://localhost/dvwa/index.php"
header={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0",
"Cookie":"security=impossible; PHPSESSID=pdujt5fsk535jscvotfma0bq26"
}
# 创建请求对象(GET请求)
req=request.Request(url,headers=header)
# 发送请求,获取响应数据
resp=request.urlopen(req).read().decode()
# print(resp)
# 定义正则,提取登录后才能获取的有效信息
pat1=r"<h1>(.*?)</h1>"
pat2=r"<em>Username:</em> (.*?)<br />"
result1=re.findall(pat1,resp)
result2=re.findall(pat2,resp)
print(result1[0]+"\n"+result2[0])
执行结果:
网友评论