爬虫学习基础

一、认识爬虫

爬虫概述:

通过编写程序爬取互联网的优秀资源(图片、音频、视频……),将我们希望能够保存互联网上的一些重要的数据为己所用。

 

推荐使用Python进行爬虫

 

软件推荐:

pycharm、anaconda、jupyter、Visual Studio Code、python(3.7及及以上版本)

 

爬虫是否合法?

取决于使用的人

善意爬虫:

不破坏爬取的网站的资源(正常访问,一般频率不高,不窃取用户隐私)

恶意爬虫:

影响网站的正常运营(抢票,秒杀,疯狂solo网站资源造成网站宕机)

 

爬虫的矛与盾:

反爬机制:

门户网站,可以通过指定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取。

反反爬策略:

爬虫程序可以通过相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而获取门户网站中相关的数据,但需注意恶意爬虫。

 

robots.txt协议:

君子协议,规定网站中那些数据可以被爬取那些数据不可被爬取。

 

 二、第一个爬虫开发案例

from urllib.request import urlopen
url = "http://www.baidu.com"
resp = urlopen(url)
#print(resp.read().decode("utf-8"))  #获取网页源代码
with open("mybaidu.html", mode="w", encoding="utf-8") as f:
    f.write(resp.read().decode("utf-8"))  #打开网页

三、web请求解析

图片解析:

直接访问、返回:

页面和数据一起加载出来

分布式:

页面和数据分开加载

 

 

四、浏览器工具的使用

 

 

 

Elements:

参考以及动态的处理一些页面上不需要的东西(如:删除一些不想要的广告)

Console:

控制台,可以做一些js的调试,进行展示

前端经常使用

Sources:

整个页面所涉及到、使用到的资源,包括页面源代码

Network:

抓包工具(可使用Fn+F12打开)

可以看到整个网页加载过程中所有的网络请求

 

 

 五、http协议

浏览器和服务器之间的数据家平湖遵守的就是HTTP协议

HTTP协议在进行数据传输时,有两种状态: 请求:

请求行-> 请求方式(get/post)请求url地址协议
请求头-> 放一些服务需要使用的附加信息
  #主要做分割作用
请求体-> 一般放一些请求参数

响应:

状态行-> 协议 状态码 (200、302、404、500)
响应头-> 放一些客户端要使用的一些附加信息 (cookie、验证信息、解密的key)
  #主要做分割作用
响应体-> 服务器返回的正真客户端要用的内容(HTML,json等)

请求头中常见的一些重要内容(爬虫需要):

1.User-Agent:请求载体的身份标识(用啥发送的请求)

2.Referer:防盗链(这次请求是从哪个页面来的?反爬会用到)

3.cookie:本地字符串数据信息(用户登录信息,反爬的token)

 

响应头中一些重要的内容: 1.cookie:本地字符串数据信息(用户登录信息,反爬的token)

2.各种神奇的莫名的字符串(这个需要经验了,一般都是token字样,防止各种攻击和反爬)

 

请求方式: GET:显示提交

POST:隐示提交

 六、正则表达式

re是 一门全新的语言,一种使用表达式的方式对字符串进行匹配的语法规则。

我们抓取到的网页源代码本质上就是一个超长的字符串,想从里面提取内容,用正则再适合不过。

优点:速度快、效率高、准确性高

缺点:新手难度高

 

在线测试网站:

https://tool.oschina.net/regex/

 

元字符具有固定意义的特殊符号

常用元字符

.        匹配除换行符以外的任意字符
    (注意:在未来Python的re模块中是一个坑——不能匹配换行符)
\w        匹配字母或数字或下划线
\d        匹配数字

^        匹配字符串的开始
$        匹配字符串的结尾

\W        匹配除了字母或数字或下划线
\D        匹配非数字
\S        匹配非空白符

a|b        匹配字符a或字符b
()        匹配括号内的表达式,也表示一个组
[...]    匹配字符组中的字符
[^...]    匹配除了字符组中字符的所有字符


*\s     匹配任意的空白符*
*\n    匹配一个换行符*
*\t    匹配一个制表符*

量词控制前面的元字符出现的次数

*        重复0次或更多次
+        重复1次或更多次
?        重复0次或一次

*{n}        重复n次*
*{n,}    重复N次或更多次*
*{n,m}    重复n到m次*

贪婪匹配和惰性匹配:

.*        贪婪匹配  #尽可能多的匹配结果
.*?        惰性匹配  #尽可能少的匹配内容——>回溯

七、re解析

re:为了防止正则表达式被误认为转义字符,通常前面加个“r”

findall:提取内容,返回列表

import re
result = re.findall("a", "我是一个abcdeafg")  
print(result)#['a', 'a']

result = re.findall(r"\d+", "我今年18岁,我有2000000000块")
print(result)  #['18', '2000000000']

finditer(重点):配内容

result = re.finditer(r"\d+", "我今年18岁")
print(result)  #得到的是迭代器
for item in result:
    print(item)
    #从迭代器中拿到内容  <re.Match object;span=(3, 5), match='18'>
    print(item.group())  
    #从匹配到的结果中拿到数据  18

search:拿到第一次匹配的内容

result = re.search(r"\d+","我叫周杰伦,今年32岁,我的班级是5年4班")
print(result.group())  #32

match:在匹配的时候,是从字符串的开头开始进行匹配的,类似在正则前面加上了^

result = re.match(r"\d+","我叫周杰伦,今年32岁,我的班级是5年4班")
print(result)  #None

预加载:提前把正则对象加载完毕

obj = re.compile(r"\d+")
#直接把加载好的正则进行使用
result = obj.findall("我叫周杰伦,今年32岁,我的班级是5年4班")
print(result)  #['32', '5', '4']

re_提取分组数据:

posted @ 2022-07-04 15:21  LackyQueen  阅读(106)  评论(0)    收藏  举报