1.爬虫的分类:即网络爬虫,模拟客户端发送网络请求,接收请求响应,按照一定规则,自动的抓取互联网信息的程序。
(1)通用爬虫:通常指搜索引擎的 爬虫,如百度搜索。通过搜索引擎搜索的局限性,其搜索的内容90%是无用的,且音频,视频,图片的内容搜索引擎无能为力(只能通过图片,视频,音频的名字进行搜索),且不同用户搜索的目的不一样,但是返回的内容相同。
(2)聚焦爬虫:针对特定网站的爬虫,如网易音乐。
2.ROBOTS协议:网站通过Robots协议告诉搜索引擎,哪些网页可以抓取,哪些不可以抓取,如https://www.taobao.com/robots.txt。
3. 简单的爬虫案例:
import requests
#设置请求头
headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}
#方法1:url和参数分开请求。
#设置搜索参数
p={"wd:"Python"}
#设置IP地址或域名
url="https://www.baidu.com/s?"
#发送请求,获取响应信息
r=requests.get(url,headers=headers,params=p)
#响应码,200为正常
print(r.status_code)
#响应的url
print(r.request.url)
#方法2:url和参数拼接在一起。
url_tem="https://www.baidu.com/s?wd={}".format("Python")
r1=requests.get(url,headers=headers)
#响应码,200为正常
print(r1.status_code)
#响应的url
print(r1.request.url)
#注意:"我是{},年龄{}岁".format("Ace",(27,))是格式化字符串。和%格式化字符串效果一样。
4. 基于requests的get方法封装一个类,爬虫爬取百度贴吧的信息:request官网:https://developer.mozilla.org/zh-CN/docs/Web/API/Request。
import requests
class BaiDuTieBa(object):
def __init__(self,tieba_name):
self.tieba_name=tieba_name
self.url_tem="https://tieba.baidu.com/f?ie=utf-8&kw="+self.tieba_name+"&fr=search&pn={}" #pn代表页数
self.headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"}
def get_url_list(self): #构造url列表,保存不同贴吧不同页面的url路径
url_list=[]
for i in range(1000):
url_list.append(self.url_tem.format(i*50)) #每50条数据一页
return url_list
#以上代码相当于:return [self.url_tem.format(i*50) for i in range(1000)]
def parse_url(self,url): #发送请求,获取响应
res=requests.get(url,headers=self.headers)
return res.content.decade() #响应获取的内容默认utf8解码
def save_html(self,html_str,page_num): #保存html字符串
file_name="{}-第{}页.html".format(self.tieba_name,page_num)
with open(file_name,"w",encoding="utf-8") as f:
f.write(html_str)
def run(self):
url_list=self.get_url_list() #构造url列表列表,用于保存url信息
for url in url_list: #循环遍历,发送请求
html_str=self.parse_url(url)
page_num=url_list.index(url)+1 #index(url)查询列表值为url时对应的下标。
self.save_html(html_str,page_num)
if __name__=="__main__":
tieba=BaiDuTieBa("lol")
tieba.run()
5. requests的post方法:如用于登录注册,传输大文本时用post方法。
(5.1)requests的post方法实现模拟浏览器手机页面的百度翻译:即浏览器f12打开移动端模拟页面,查看的发送的参数和接受的参数。
import requests
import json
class BaiDuFanYi(object):
def__init__(self,trans.str):
self.trans_str=trans.str #要翻译的词语
self.lang_url="https://fanyi.baidu.com/langdetect" #判断要翻译的语言类型,中文还是英文
self.trans_url="https://fanyi.baidu.com/basetrans" #执行翻译的url
self.headers={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) #模拟浏览器的浏览器信息和电脑/手机基本信息
def send_url(self,url,data): #发送post请求,获取响应
res=requests.post(url,data=data,headers=self.headers)
return json.loads(res.content.decode()) #将获取的响应字符串信息解码,并将json字符串转换为python类型(如字典),json.dumps(a)是将python类型转换为json字符串,如用于f.write(json.dumps(a)),文件写入字符串类型。
def run(self):
#1.获取语言类型
lang_data={"query":self.trans_str} #这是要翻译的语言的字典参数
lang=self.send_url( self.lang_url,lang_data) #获取要翻译的语言的类型
#2.准备post的数据
trans_data=null;
if lang=="zh": #如果要翻译的语言类型时中午,就将中文翻译英文,否则将英文翻译成中文
trans_data={"query": "你好","from": "zh","to": "en"}
else:
trans_data={"query": "你好","from": "en","to": "zh"}
#3.发送请求获取响应
result=send_url(self.trans_url,trans_data) #返回的整个json对象
#4.提取翻译结果
print(result["trans"][0]["dst"])
"""
如result的结果如下:
{
dict: {word_name: "你好", from: "kingsoft", word_means: ["hello", "hi"},
en_ph: {ph_am_mp3: "/1/0/5d/41/5d41402abc4b2a76b9719d911017c592.mp3", ph_am: "həˈloʊ", ph_en_mp3: ""},
errno: 0,
from: "zh",
to: "en",
trans: [{
dst: "Hello",
prefixWrap: 0,
relation: [],
result: [[0, "Hello", ["0|6"], [], ["0|6"], ["0|5"]]],
src: "你好",
}]
}
"""
if __name__=="__main__":
baidu_fanyi=BaiDuFanYi("欢迎来到爬虫的世界")
baidu_fanyi.run()
6. 使用代理:分为正向代理,反向代理。
(6.1)爬虫使用代理的目的:让服务器以为不是同一个客户端在请求,防止真实客服端地址被泄露。
(6.2)如何使用代理:
a. 准备一堆ip地址,组成ip池,每次请求随机选择一个ip来用。
b. 如何随机选择代理ip,让使用次数较少的ip地址有更大的可能性被用到。
——{"ip":ip,"times":5}
——[{},{},{}]对该ip池列表按照使用次数times升序或降序排列。
——选择使用次数较少的10个ip地址,从中随机选择一个。
c. 检查IP的可用性。
——可以使用requests添加超时参数,判断ip地址的质量。
——在线代理ip质量检测网站。
import requests
proxies={"http":"http://163.177.151.23:80"} #使用代理ip地址,如(米扑代理,高匿代理)。
header={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"}
r=requests.get("http://www.baid.com",proxies=proxies,headers=headers)
print(r.status_code) //测试代理IP地址是否可以(即返回200),以及延迟时间。
#使用request保存图片,视频等
res=requests.get("http://www.baid.com/img/logo.png")
#将图片,视频保存在本地,因为图片,视频等是二进制内容,所有用"wb"
with open("1.png","wb") as f:
f.write(res.content)
7. cookie和session:如使用session和cookie实现三种方式的登录。
import requests
#三种方式实现登录:
#方法1:
headers={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1"}
#1.1实例化session。
session=requests.session()
url="http://www.renren.com/SysHome.do"
data={
"email":"[email protected]",
"password":"Ace123456"
}
#1.2使用session发送post请求,cookie保存在其中。
session.post(url,data=data,headers=headers)
#1.3使用session进行登录之后才能访问的地址,并保存其返回的页面数据。
r=session.get("http://www.renren.com/132472/profile",headers=headers)
#1.4保存页面
with open("登录方法1.html","w",encoding="utf-8") as f:
f.write(r.content.decode())
#方法2:
#2.1 将还在有效期的cookie,保存在headers中。
headers={
"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1",
"Cookie":"BAIDUID=70729A5D993538065F1B46ABCDCAB740:FG=1;
BIDUPSID=70729A5D993538065F1B46ABCDCAB740; PSTM=1539427327; BDUSS=EhZb3NzS1hiQi1JWDdrVlExU0"
}
r=requests.get("http://www.renren.com/132472/profile",headers=headers)
#2.2保存页面
with open("登录方法2.html","w",encoding="utf-8") as f:
f.write(r.content.decode())
#方法3:
#3.1 将字典cookie作为参数传入
headers={
"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1",
}
cookie={}
r=requests.get("http://www.renren.com/132472/profile",headers=headers,cookie=cookie)
#3.2保存页面
with open("登录方法2.html","w",encoding="utf-8") as f:
f.write(r.content.decode())
8. 数据提取:即从响应回来的数据中获取我们需要的数据,存在数据库中。
数据分类:(1)非结构化数据:HTML等。
处理方式:正则,xpath。
(2)结构化数据:json.xml等。
处理方式:转换为json数据类型。