文章目录
- 前言
- 概述
- 简单爬虫
- requests模块⼊⻔
- 数据解析
- re解析
- re模块
- 总结
前言
本博客仅做学习笔记,如有侵权,联系后即刻更改
科普:
学习参考网站
概述
安全
爬⾍在法律上是不被禁⽌的
- 像王欣说过,技术是⽆罪的. 主要看你⽤它来⼲嘛
robots.txt协议
- 规定了⽹站中哪些数据可以被爬⾍爬取,哪些数据不可以被爬取
在这里插入图片描述
简单爬虫
urllib爬取百度首页
from urllib.request import urlopen
resp = urlopen("http://www.baidu.com") # 打开 百度
# print(resp.read().decode("utf-8")) # 打印 抓取到
的内容
with open("baidu.html",mode="w", encoding="utf-8")
as f: # 创建⽂件
f.write(resp.read().decode("utf-8")) # 保存在
⽂件中
web请求过程
浏览器渲染
- 请求到服务器的时候
服务器直接把数据全部写⼊到html中, 我们浏览器就能直接拿到带有数据的html内容客户端渲染
- 是第⼀次请求服务器返回⼀堆HTML框架结构
然后再次请求到真正保存数据的服务器, 由这个服务器返回数据, 最后在浏览器上对数据进⾏加载
HTTP协议
Hyper Text Transfer Protocol(超⽂本传输协议)
- ⽤于从万维⽹(WWW:World Wide Web )服务器传输超⽂本(HTML)到本地浏览器的传送协议
请求和响应都分为三部分
请求头中重要部分
- User-Agent : 请求载体的身份标识(⽤啥发送的请求)
- Referer: 防盗链(这次请求是从哪个⻚⾯来的? 反爬会⽤到)
- cookie: 本地字符串数据信息(⽤户登录信息, 反爬的token)
响应头中⼀些重要的内容:
- cookie: 本地字符串数据信息(⽤户登录信息, 反爬的token)
- 各种神奇的莫名其妙的字符串(⼀般都是token字样, 防⽌各种攻击和反爬)
请求方式分为get和post(隐式提交)
requests模块⼊⻔
第三⽅模块requests
- 这个模块的优势就是⽐urllib还要简单, 并且处理各种请求都⽐较⽅便
使用方法
既然是第三⽅模块, 那就需要我们对该模块进⾏安装
- pip install requests
如果安装速度慢的话可以改⽤国内的源进⾏下载安装.
- pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
爬取搜狗搜索
# 案例1. 抓取搜狗搜索内容
kw = input("请输⼊你要搜索的内容:")
response =
requests.get(f"https://www.sogou.com/web?query=
{kw}") # 发送get请求
# print(response.text) # 直接拿结果(⽂本)
with open("sogou.html", mode="w", encoding="utf8") as f:
f.write(response.text)
爬取百度翻译
注意百度翻译这个url不好弄出来. 记住, 在输⼊的时候, 关掉各种输⼊法,要⽤英⽂输⼊法, 然后不要回⻋. 就能看到这个sug了
# 案例2.抓取百度翻译数据
# 准备参数
kw = input("请输⼊你要翻译的英语单词:")
dic = {
"kw": kw # 这⾥要和抓包⼯具⾥的参数⼀致.
}
# 请注意百度翻译的sug这个url. 它是通过post⽅式进⾏提交
的. 所以我们也要模拟post请求
resp =
requests.post("https://fanyi.baidu.com/sug",
data=dic)
# 返回值是json 那就可以直接解析成json
resp_json = resp.json()
# {'errno': 0, 'data': [{'k': 'Apple', 'v': 'n.
苹果公司,原称苹果电脑公司'....
print(resp_json['data'][0]['v']) # 拿到返回字典中的
内容
爬取豆瓣
有⼀些⽹站在进⾏请求的时候会校验你的客户端设备型号
# 案例3: 抓取⾖瓣电影
url = 'https://movie.douban.com/j/chart/top_list'
param = {
'type': '24',
'interval_id': '100:90',
'action':''
,
'start': '0',#从库中的第⼏部电影去取
'limit': '20',#⼀次取出的个数
}
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel
Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/72.0.3626.121 Safari/537.36'
}
response =
requests.get(url=url,params=param,headers=headers
)
list_data = response.json()
fp = open('./douban.json','w',encoding='utf-8')
json.dump(list_data,fp=fp,ensure_ascii=False)
print('over!!!')
数据解析
网页数据提取
- re解析
- bs4解析
- xpath解析
这三种⽅式可以混合进⾏使⽤, 完全以结果做导向, 只要能拿到你想要的数据. ⽤什么⽅案并不重要.当你掌握了这些之后. 再考虑性能的问题
re解析
Regular Expression, 正则表达式
⼀种使⽤表达式的⽅式对字符串进⾏匹配的语法规则
- 我们抓取到的⽹⻚源代码本质上就是⼀个超⻓的字符串, 想从⾥⾯提取内容.⽤正则再合适不过了
在线测试正则表达式
正则表达式相关概念
元字符
- 具有固定含义的特殊符号
常用元字符
量词: 控制前⾯的元字符出现的次数
贪婪匹配和惰性匹配
re模块
常用功能
- findall
查找所有. 返回list
lst = re.findall("m", "mai le fo len, mai ni
mei!")
print(lst) # ['m', 'm', 'm']
lst = re.findall(r"\d+", "5点之前. 你要给我5000
万")
print(lst) # ['5', '5000']
- search
会进⾏匹配. 但是如果匹配到了第⼀个结果. 就会返回这个结果. 如果匹配不上search返回的则是None
ret = re.search(r'\d', '5点之前. 你要给我5000
万').group()
print(ret) # 5
- match
只能从字符串的开头进⾏匹配
ret = re.match('a', 'abc').group()
print(ret) # a
- finditer
和findall差不多. 只不过这时返回的是迭代器(重点)
it = re.finditer("m", "mai le fo len, mai ni
mei!")
for el in it:
print(el.group()) # 依然需要分组
- compile()
可以将⼀个⻓⻓的正则进⾏预加载. ⽅便后⾯的使⽤
obj = re.compile(r'\d{3}') # 将正则表达式编译成为
⼀个 正则表达式对象, 规则要匹配的是3个数字
ret = obj.search('abc123eeee') # 正则表达式对象调
⽤search, 参数为待匹配的字符串
print(ret.group()) # 结果: 123
- 正则中的内容如何单独提取?
单独获取到正则中的具体内容可以给分组起名字
将正则表达式括号包裹,加?P<分组名字>
例子:(?P\d+)
s = """
<div class='⻄游记'><span id='10010'>中国联通
</span></div>
"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?
P<name>\w+)</span>", re.S)
result = obj.search(s)
print(result.group()) # 结果: <span
id='10010'>中国联通</span>
print(result.group("id")) # 结果: 10010 # 获取
id组的内容
print(result.group("name")) # 结果: 中国联通 #
获取name组的内容
总结
小小励志
有些事你现在不做,一辈子都不会做了。
如果你想做一件事,全世界都会为你让路。
《搭车去柏林》