爬虫的定义
网络爬虫,即Web Spider,是一个很形象的名字。把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。网络蜘蛛是通过网页的链接地址来寻找网页的。 如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。这样看来,网络爬虫就是一个爬行程序,一个抓取网页的程序。网络爬虫的基本操作是抓取网页。
通用爬虫与聚焦爬虫的区别
通用爬虫:目标、流程(爬取网页 - 存储数据 - 内容处理 - 提供检索/排名服务)、遵循Robots协议、缺点。聚焦爬虫,是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于: 聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。
各类爬虫框架比较
如果是定向爬取几个页面,做一些简单的页面解析,爬取效率不是核心要求,那么用什么语言差异不大。
如果是定向爬取,且主要目标是解析js动态生成的内容
如果爬虫是涉及大规模网站爬取,效率、扩展性、可维护性等是必须考虑的因素时候
反爬虫技术
1.通过User-Agent来控制访问
2.通过IP限制来反爬虫
3.通过JS脚本来防止爬虫
4.通过robots.txt来限制爬虫
反反爬虫技术
1. 构造合理的 HTTP 请求头
2. 设置合理的cookie
3. 爬虫访问速度和路径的控制
4. 注意网页隐藏的信息
5. 避免进入蜜罐
6. 使用可变IP
Requests的安装
windows打开终端输入cmd
输入
pip install requests
Requests之Get请求
get 一般的a标签,点击跳转的,或者直接在浏览器地址栏输入的 这种都是 get方式
# 请求百度网页
import requests
url = "http://www.baidu.com"
response = requests.get(url)
print(response)#返回状态值
print(type(response))#打印出类别
获取返回的源码,默认解析编码,自动解析编码解析,有时可能出现乱码:response.text
print(response.text)
获取返回的字节码加上decode("编码")指定编码解析:response.content
print(response.content.decode("utf-8"))
返回网页的编码,自动检测编码
print(response.encoding)#获取返回时编码,自动检测编码
获取状态码status_code
# 1** 正在请求
# 2** 请求成功,有返回值
# 3** 网页重定向
# 4** 请求的资源错误 404
# 5** 服务器错误(502)
print(response.status_code)
headers 消息头(一般用来设置 UA 和 Referer)
# User-Agent 用户代理 (当前访问网站使用的浏览器) 反爬虫策略中的一种,UA检测
# Referer 上一页链接(来源页) 部分网站会通过上一页的链接检测 ,做反爬虫
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36"
}
requests.get(url,headers=headers)
比如在爬知乎网站时没有加入消息头就会被拒绝访问
url = "http://httpbin.org/get"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67."}
response = requests.get(url,headers=headers)
print(response.text)
params给url传参
第一种传参:
url = "http://httpbin.org/get"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67."}
params = {"name":"Tom",
"age":"22"
}
response = requests.get(url,headers=headers,params=params)
print(response.text)
print(type(response.text))
第二种传参
url="http://httpbin.org/get?sex='男'&age=19"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67."}
params = {"name":"Tom",
"age":"22"
}
# response = requests.get(url,headers=headers,params=params)
response = requests.get(url,headers=headers)
print(response.text)
print(type(response.text))
请求资源文件
url="https://www.baidu.com/img/superlogo_c4d7df0a003d3db9b65e9ef0fe6da1ec.png?where=super"
r=requests.get(url,headers=headers)
print(r.content)
with open("baidu.png",'wb') as file:
file.write(r.content)
stream=True 流式传输,可以每次读取一部分,而不是一次性的下载全部的大小,然后一次性写入
r=requests.get(url,stream=True)
with open("",'wb') as file: # 新建一个文件
for j in r.iter_content(10240) #每次读取10kb
file.write(j) # 每次写入10kb
mp3_url="https://m10.music.126.net/20190617214827/d2f9934617a5a0e7dbf93ef2bf4130f5/yyaac/555a/535e/5609/b043a4e717d47fc89a1cac04ed44166f.m4a"
r=requests.get(mp3_url,headers=headers,stream=True)
with open("TwentySomething.mp3",'wb') as file:
for j in r.iter_content(10240):
file.write(j)
timeout=1 设定最大等待时间
requests.get(url,timeout=2) #超过2秒后如果没有返回值,就不再等待,直接报错结束
# timeout 超时设置
# url="http://httpbin.org/get"
# r=requests.get(url,timeout=0.1)
# print(r.text)
proxies={} 设置代理
proxies={
"http":"IP:port",
"https":"IP:port"
}
requests.get(url,proxies=proxies)
# 设置代理 proxies
url="http://httpbin.org/get"
# 101.229.216.43
proxies={
"http":"175.102.3.98:8089"
}
r=requests.get(url,proxies=proxies)
print(r.text)
verify=False 不验证证书
r.json() 使用 response对象 直接解析成 json
把json字符串解析成 字典,但是没有办法解析html,只能解析 类似字典或者列表的字符串
如果是单独的 python字符串 里面包含 json字符串的话,需要使用json模块
import json
json.loads(str) 把json字符串转换成 字典或者列表
json.dumps(dict|list) 把列表或者字典转换成 json字符串
url = "http://httpbin.org/get"
# url="http://httpbin.org/get?sex='男'&age=19"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67."}
params = {"name":"Tom",
"age":"22"
}
response = requests.get(url,headers=headers,params=params)
result = response.json()
print(result['origin'])
对字符串的处理
import json
str = '{"name":"Mike"}'
print(json.loads(str))
Requests之post请求
# 发起 POST 请求
r=requests.post() # 跟get相同
# data={} 传参的时候 使用 data=data
data={
'uname':"xiaoming",
'upwd':"123456"
}
r=requests.post(url,data=data) # 传form表单数据
r=requests.post(url,data=json.dumps(data)) # 传json数据
# files={} 向服务器发送资源
fp=open("1.png",'rb')
files={"img":fp}
r=requests.post(url,files=files)
使用post方式传值
# url="http://httpbin.org/post"
# # data={"uanme":'xiaohong','upwd':123546}
# fp=open("baidu.png",'rb')
# fp2=open("爬虫.note",'rb')
# files={
# "file_baidu":fp,
# 'file_note':fp2
# }
# json_data=json.dumps({"aa":"bb","cc":"11"})
#
# r=requests.post(url,data=json_data)
# print(r.text)