Python爬虫(第一周)
目录
一、正则表达式
正则表达式的作用
正则表达式的使用
1.match函数
匹配单个字符(规范字符类型)
匹配多个字符(规范字符数量)
匹配开头和结尾
2.search函数
小案例
3.findall函数
4.贪婪与非贪婪
二、爬虫
爬虫的概念
网络通信
爬虫的分类
爬虫的基本流程
一、正则表达式
正则表达式的作用
爬虫:数据的提取
例如:从 xxxxxxxxx.www.baidu.comxxxxxxx中将www.baidu.com提取出来
前后端:数据的规范
例如:检验用户输入的手机号是不是十一位数字
正则表达式:不是独属于Python的,是跨语言的。
正则表达式的使用
# 导入re模块 (他只是一个python文件:re.py)
import re
导入re模块后,当我们输入 re. 后Pycharm会自动提示有哪些可用的函数和方法
下面我们介绍一些在爬虫中常用的函数和方法
1.match函数
def match(pattern, string, flags=0):"""Try to apply the pattern at the start of the string, returninga Match object, or None if no match was found."""return _compile(pattern, flags).match(string)
我们从re.py中查看match函数,可以看到match函数有两个必须传值的形参(pattern,string)和一个默认参数(flags)
pattern:传入正则表达式(提取规则,即提取内容需要满足的条件)
string:传入字符串(从该字符串中提取内容)
其次,match函数有返回值,所以我们在调用时需要一个变量进行返回值的接收
import re# 目的:判断s字符串是不是以hello开头
s = 'hello,python'
res_ = re.match(r'hello', s)
print(res_) # 返回值: <re.Match object; span=(0, 5), match='hello'>
match的返回值是一个对象,只要目标字符串出现,match函数就是匹配成功的
匹配不成功返回值是:None
匹配单个字符(规范字符类型)
需求:豆瓣电影中有很多的电影,但我们只想要匹配哈利波特1-7部的,那我们应该怎么做呢?
# 匹配七次
import rere.match(r'哈利波特1','哈利波特1')
re.match(r'哈利波特2','哈利波特2')
re.match(r'哈利波特3','哈利波特3')
re.match(r'哈利波特4','哈利波特4')
re.match(r'哈利波特5','哈利波特5')
re.match(r'哈利波特6','哈利波特6')
re.match(r'哈利波特7','哈利波特7')
以上代码缺点很明显,七部电影需要匹配七次,非常麻烦,那我们有什么通用一点的办法吗?
所以我们引入单个字符的匹配
# 通用办法
import reres_ = re.match(r'哈利波特\d','哈利波特6') # \d可以代表一位数字
print(res_)
在这种情况下,第二个参数无论是哈利波特1,还是哈利波特2,还是哈利波特3......都可以匹配成功,可是这会出现另一个问题,我们到底匹配成功的是哪一部呢?是1还是2,3,4?所以匹配到的数据我们可以通过group()方法接收
data = res_.group()
print(data)
问题:当网站数据出现问题,比如多出来部哈利波特8,而实际上没有这部电影,我们通过上面的办法也会将哈利波特8匹配成功,所以当需求不一样时,我们的匹配规则也需要变化
import reres_ = re.match(r'哈利波特[1234567]', '哈利波特8') # []:表示匹配[]中列举的一个字符
# res_ = re.match(r'哈利波特[1-7]', '哈利波特8') # 简单写法
print(res_) # 匹配不成功
[ ]中的内容在一些情况下有简单写法:1. 数字:0-9
2. 小写字母:a-z
3. 大写字母:A-Z
在这里,我们给出单个字符匹配的规则表
. | 匹配任意1个字符(除了\n之外) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配单个数字:0,1,2,3,4,5,6,7,8,9 |
\D | 匹配非数字 |
\s | 匹配空白,即空格和Tab(缩进) |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z,A-Z,0-9,_ |
\W | 匹配非单词字符 |
\w 不推荐使用,匹配内容非官网文档所介绍的:a-z,A-Z,0-9,_
import reres_ = re.match(r'哈利波特\w', '哈利波特一')
print(res_)
按照官方文档中介绍的规则,是应该匹配失败的,但是实际上是匹配成功的
匹配多个字符(规范字符数量)
问题:如果哈利波特拍的太好了,出到了第11部,那我们该如何匹配呢?
import reres_ = re.match(r'哈利波特\d','哈利波特11') # \d可以代表一位数字
print(res_)
如果使用匹配单个字符的方法,上述代码匹配到的结果是:哈利波特1
所以要想实现我们的目的,需要引入匹配多个字符,下面是一些常用的匹配规则:
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出啊先1次或者无限次,即至少有1次 |
? | 匹配前一个字符出现1次或者0次,即要么有1次要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现m到n次 |
重点:匹配前一个字符,即依赖前一个字符
import re# 解决电影名称的问题
res_ = re.match(r'哈利波特\d{1,2}','哈利波特11') # \d可以代表一位数字,{1,2}表示1到2位
print(res_)# 匹配电话号
res_1 = re.match(r'\d{11}', '15193039859') # 匹配11位数字
print(res_1)
phone_ = res_1.group()
print(phone_)# 匹配qq号
res_2 = re.match(r'\d{6,12}', '925290303') # 匹配6-12位数字
print(res_2)
qq_number = res_2.group()
print(qq_number)
匹配开头和结尾
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
2.search函数
import re# match和search的区别
# 匹配中间的数字
s = 'abc123456def'res_1 = re.match(r'\d{6}', s)
print(res_1) # Noneres_2 = re.search(r'\d{6}', s)
print(res_2) # <re.Match object; span=(3, 9), match='123456'>
match函数默认匹配开头
search函数从开头开始搜索,匹配到符合规范的返回结果
小案例
匹配QQ邮箱:qq号+@qq.com
分析:1. 6-12位的qq号
2. @后面的qq可以大写可以小写
3. 以com结尾
import reemail_ = input('请输入QQ邮箱:')res_ = re.match(r'\d{6,12}@[Qq]{2}.com', email)
print(res_)
上述代码看似正确,但是存在一些小bug:输入925290303@qq#com时匹配成功
输入925290303@qq.comm时匹配成功
分析:1. 在正则表达式中,“ . ”表示匹配任意一个字符(\n)除外,所以会出现第一种匹配成功
2. match默认匹配开头,当满足“ \d{6,12}@[Qq]{2}.com ” 时无论后面再出现什么字符都会匹配成功
解决:1. [ ] , . , * , ? 只是当普通字符出现,而不是作为正则表达式的规则出现时,我们需要对其进行转义操作:在这些字符前面加上 \ 即可
2. 在match匹配时规定匹配结尾
import reemail_ = input('请输入QQ邮箱:')res_ = re.match(r'\d{6,12}@[Qq]{2}\.com$', email)
print(res_)
分组
import reemail_ = input('请输入QQ邮箱:')res_ = re.match(r'\d{6,12}@(qq|QQ)\.com$', email) # qq,QQ其中任意一个都行
print(res_)
()可以进行分组,括号里的是单独的逻辑作用不到外面
3.findall函数
引入:我们得到的3个人的qq号信息:小明:123456789,小王:23456789,小李:3215647 我们需要将三个人的qq号都提取出来,此时search和match都不能满足我们的需求,就需要使用一个新的函数:findall来实现
import reinfo_ = '小明:123456789,小王:23456789,小李:3215647'res_1 = re.search(r'\d+', info_)
print(res_1)
print(res_1.group()) # 123456789res_2 = re.findall(r'\d+', info_)
print(res_2) # ['123456789', '23456789', '3215647']
从中我们可以发现区别:
search函数匹配到一个符合规范的就返回结果,不继续搜索,返回值为对象
findall函数匹配所有符合规范的结果,返回值为由符合规范结果构成的列表,没有匹配到返回一个空列表
无论需要匹配几个一般都采用findall函数,search函数在没有匹配到符合规则的内容时调用group方法会报错(影响程序运行),findall没有匹配到符合规则的内容时返回空列表
我们可以使用findall函数和()分组获取长字符串中符合规则的内容
import res = '<link data-vue-meta="true" rel="canonical" href="https://www.bilibili.com/video/BV1Zs41137Tr/">'# 从标签中提取视频链接
url_ = re.findall(r'<link data-vue-meta="true" rel="canonical" href="(.*)">', s)
print(url_)
4.贪婪与非贪婪
贪婪:正则表达式默认是贪婪的,取得越多越好
非贪婪:加上一个 ?,只匹配第一个满足的
import res = '<link data-vue-meta="true" rel="canonical" href="https://www.bilibili.com/video/BV1Zs41137Tr/">'# 从标签中提取视频链接(非贪婪)
url_ = re.findall(r'<link data-vue-meta="true" rel="canonical" href="(.*?)">', s)
print(url_)
二、爬虫
爬虫的概念
爬虫就是模拟客户端发送网络请求,接受请求对应的响应,按照一定的规则自动抓取互联网信息的程序。
客户端(浏览器),一般情况下操作者是正常用户,当我们用爬虫模拟客户端时,服务器时不欢迎我们的,所以我们应该尽可能的去模拟正常用户去发送请求。
爬虫:模拟客户端访问,抓取数据 ---> 我们做的事情
反爬:保护重要数据,阻止恶意网络攻击 ---> 网站的后端服务器,识别爬虫
反反爬:针对反爬措施 ---> 我们做的事情,尽量模拟正常用户:1.属性(静态)
2.行为(动态)
网络通信
1.电脑(浏览器)输入url:www.baidu.com(域名)
2.DNS服务器:IP地址标注的服务器 由www.baidu.com找到对应的IP地址1.1.1.1,DNS服务器将IP地址返回给浏览器
3.浏览器拿到IP地址去访问服务器,返回响应
一个请求(www.baidu.com)只能对应一个数据包(文件),就好比www.baidu.com这个请求,实际上只能获取到一个数据包:html数据,他是不包含图片、css、js的,但是我们在www.baidu.com的Networks里面看到了n个数据包,这些数据包共同组成了这个页面(n个数据包 -> n个请求 - > n个不同的url)。而产生这种现象都是浏览器的功劳:浏览器会帮助我们把url(www.baidu.com -> https://www.baidu.com/)补全,得到这个数据包(www.baidu.com)的响应,浏览器发现,这个数据包(www.baidu.com)的响应里面缺少了很多东西,对于这些缺少的部分浏览器会自动帮我们发送请求,获取响应,渲染完整,最终组成完整的页面。
爬虫的分类
通用爬虫 | 通常值搜索引擎和大型Web服务提供商的爬虫 | |
聚焦爬虫 (针对特定网站的爬虫,定向的获取某方面数据的爬虫) |
累计式爬虫 | 从开始到结束,不断进行爬取,过程中进行去重操作 |
增量式爬虫 | 已下载网页采取增量式更新和只爬取新产生的或者已经发生变化网页的爬虫 | |
Deep Web爬虫 | 不断通过静态链接获取的,隐藏在搜索表单后的,只有用户提交一些关键词才能获得的web页面 |
爬虫的基本流程
1.确认目标:确认目标的url:www.baidu.com
2.发送请求:发送网络请求,获取特定的服务端给你的响应
3.提取数据:从响应中提取到特定的数据,jsonpath,xpath为主,re为辅
4.保存:本地(html,json,txt)或者数据库
获取到的响应当中,有可能提取到了还需要发送请求的url,我们就拿着解析到的url继续发送请求
Python爬虫(第一周)相关推荐
- python 爬虫 第一周:学会爬取网页信息
1.安装库 确保python和系统的版本一致,32 or 64 , pip --version 查看pip版本 Soup = BeautifulSoup(html,'lxml') 汤 ...
- python123第一周作业答案程序题_[python爬虫]第一周作业_顾静
第一次作业 第一题 a = 10,b = 3 计算下面c的值及输出数据类型 1.c = a/b - a 2.c = a/b * a 3.c = 0.1 * a//b - a 4.c = a//b + ...
- python学习第一周总结
python学习第一周总结 一.Markdown语法 Markdown是一种轻量级标记语言,排版语法简洁,它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML.PDF 以及本身的 . ...
- 无字天书之Python爬虫第一页
博客内容 主体 什么是爬虫? 为什么要用爬虫? 各路神仙没有丝毫反馈啊-小编更新的没有动力了啊 许久不见,并不是被感染了,别怕啊,咱不会隔着电脑把你传染了... 放在CSDN草稿箱中太久了-拿出来更新 ...
- 01 Python学习--第一周--开课介绍、数据类型、数据运算、表达式、循环、三元运算、对象基本概念...
模块一主要内容 开课介绍 python发展介绍 第一个python程序 变量 字符编码与二进制 字符编码的区别与介绍 用户交互程序 if else流程判断 while 循环 while 循环优化版本 ...
- python学习第一周(1)
备注:一般规范代码,可以操作code-reformat code 1. #!/usr/bin/env python 脚本语言第一行 作用:文件中代码用指定可执行程序运行,在unix类的操作系统才有意义 ...
- Python基础第一周--Python语言家族
在这里插入图片描述 一.Python语言家族 1 Introduction 1.1 Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. 简单来说,Pyt ...
- Python基础第一周
一.Python语言家族 1 Introduction 1.1 Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. 简单来说,Python是一门编程语言 ...
- python爬虫--第一个爬虫程序
一.爬虫基本知识 URL(Uniform Resource Locator的缩写):也被称为网页地址,通俗讲就是文件在网络中的位置,URL就是web地址,俗称"网址". HTTP是 ...
- Python爬虫——第一个小爬虫(经典)修改版
贴吧图片的爬取 一.页面获取 要让python可以进行对网页的访问,那肯定要用到urllib之类的包.So先来个 import urllib.request 由于Python3里的urllib模块已经 ...
最新文章
- 二叉树后序遍历-递归与非递归(左右根)
- Nginx + Lua + redis (一)(转)
- spring boot + vue + element-ui全栈开发入门——前后端整合开发
- 利用 SIFT 实现图像拼接
- php如何缩小图片,PHP图片缩小函数一例
- 课堂练习-买书价格最低
- java8默认垃圾回收器,Java 8的默认垃圾收集器
- 英特尔强势上新一大波数据产品,小伙伴们“奔走相告”…… | 极客头条
- LAMP架构调优(四)——资源压缩传输
- 19. Rootkit detectors (隐形工具包检测器 5个)
- 学web前端从哪里开始学起呢-好程序员
- 蓝牙耳机测试软件apk_AndPods蓝牙耳机管理器.apkv1.5.2 免费版 Android
- 渐进式jpg转换成基线式 jpg
- 实习生快速入手项目php,2019.7最惨的三次面试经历-----百度PHP实习生面经
- Unexpected exception encountered during query.解决办法
- 滥用exchage远程调用域管理员API接口
- 如何以活动价在官网购买百度网盘会员
- found zsh 所有命令在终端失效
- 使用canvas 代码画小猪佩奇
- WIN7中文专业版安装日文语言包的方法
热门文章
- 我的程序员工作经历(一) 之 苦逼了
- 用python做一张图片_用Python实现将一张图片分成9宫格的示例
- db2数据库日志已满的解决办法
- 16个实用的.htaccess设置
- 我的python世界下载_我的Python世界
- java时间戳计算_java 时间戳 、时间差计算(秒、分钟、小时、天数、月份、年)...
- 换季敏感起皮还冒痘,到底该如何维稳肌肤呢?
- Python语言-NL-工作日的努力
- 完整视频播放器封装库 1
- mem.h是C语言头文件吗,说那个“mem.h”头文件打不开 怎么改啊 高手们帮帮忙