内容正文:
筐鱼梧领凤峡匪跑脚凡辅乒踪勿久褂舟婴袭剪肚爹伦甄啸镣娟附卉态再骂广东农工商职业技术学院PPT模板-精美原创毕业论文答辩广东农工商职业技术学院PPT模板-精美原创毕业论文答辩
项目11 综合项目——字符串与Python 爬虫基础
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目介绍
项目背景
爬虫是一个程序,它的任务是从给出的一组种子网址(URL)开始爬取网页,并通过网页间的链接爬取更多的网页,根据爬虫任务的需求,最终可能会爬取整个互联网的网页。爬虫的最终目的是按照用户需求获取网页中的内容。在大数据相关任务中,主要被用来进行数据获取和提取,以及一定的数据预处理功能。
本项目围绕爬虫任务,介绍爬虫所需的字符串和正则表达式等相关概念,最后为大家展示一个完整的爬虫任务。
项目介绍
项目规划
01
熟练掌握字符串的概念和各种用法,以及Python标准库string的使用。
02
了解正则表达式的概念和用法
03
能写出具备一定功能的爬虫
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目目标
知识目标
1
掌握字符串的概念
2
掌握Python标准库string的函数和常量
3
了解正则表达式和元字符的概念
项目目标
能力目标
1
掌握字符串和string类的使用
2
会使用正则表达式和元字符
3
能运用以上知识完成简单爬虫的设计
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
项目准备
1. 字符串编码
字符要在计算机中存储和显示,就要对其进行编码。最初,普遍使用ASCII(American Standard Code for Information Interchange,美国信息交换标准代码),但它主要用于现代英语和其他西欧语言。
Python3 默认使用UTF-8编码。经常会在Python源文件的开头看到一行注释:
1)编码
# coding=utf-8
项目准备
1. 字符串编码
Python3支持两种类型字符串:str类型(支持Unicode编码)和bytes类型,两种类型之间可以相互转换。
2)Python 字符串类型
项目准备
1. 字符串编码
2)Python 字符串类型
>>> s='人'
>>> s
'人'
>>> type(s) # s是str类型字符串
<class 'str'>
>>> s_gbk=s.encode('gbk') # 编码成bytes类型,gbk编码格式
>>> s_gbk
b'\xc8\xcb'
>>> type(s_gbk) # s_gbk是bytes类型字符串
<class 'bytes'>
>>> s_utf8=s.encode('utf-8') # 编码成bytes类型,utf-8编码格式
>>> s_utf8
b' \xe4\xba\xba' # 注意!utf-8编码用3个字节来表示1个汉字
>>> type(s_utf8) # s_utf8是bytes类型字符串
<class 'bytes'>
>>> s_gbk_de=s1.decode('gbk') # 使用gbk进行解码
>>> s_gbk_de
'人'
>>> type(s_gbk_de) # s_gbk_de是str类型
<class 'str'>
>>> s_utf8_de =s2.decode('utf-8') # 使用utf-8进行解码
>>> s_utf8_de
'我'
>>> type(s_utf8_de) # s_utf8_de是str类型
<class 'str'>
>>> s_asc=s.encode('ascii') # 中文字符串不能以ascii编码
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
s_asc =s.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\u6211' in position 0: ordinal not in range(128)
项目准备
2. 构造字符串
Python中,构造字符串主要有两种方式:引号(单引号、双引号或三引号)和str()函数。
1)字符串构造
>>> a = 'Python World!'
'Python World!'
>>> a = ''Python World! ''
''Python World! ''
>>> a = str('Python World!')
'Python World!'
项目准备
2. 构造字符串
如果代码中的字符串包含了单引号,且不用转义字符,那么整个字符串就要用双引号来构造,否则就会出错。
如果代码中的字符串包含了双引号,且不用转义字符,那么整个字符串要用单引号来构造。
1)字符串构造
>>> "Let's go!"
"Let's go!"
>>> print("Let's go!") # print()函数输出更直观
Let's go!
>>> 'Let's go!'
SyntaxError: invalid syntax
>>> '"Hello world!",he said.'
'"Hello world!",he said.'
>>> print('"Hello world!",he said.') # print()函数输出更直观
"Hello world!",he said.
项目准备
2. 构造字符串
'Let's go!' 的语法错误可以用下面方法解决:
2)转义字符
>>> 'Let\'s go!' # \' 为转义字符,代表单引号。\为转义标识。
"Let's go!"
>>> print('Let\'s go!')
Let's go!
项目准备
2. 构造字符串
转义字符以“\”开头,后接某些特定的字符或数字。Python中常用的转义字符如表所示。
2)转义字符
转义字符 含义 转义字符 含义 转义字符 含义
\(行尾) 续行符
换行符 \f 换页符
\\ 一个反斜杠\ \r 回车 \ooo 3位8进制数ooo对应的字符
\’ 单引号’ \t 横向(水平)制表符 \xhh 2位16进制数hh对应的字符
\” 双引号” \v 纵向(垂直)制表符 \uhhhh 4位16进制数hhhh表示的Unicode字符
项目准备
2. 构造字符串
Python提供了比转义字符更简洁的保留字符格式的方法——原始字符。在字符串前面加上字母r或R,所有的字符都是原始的本义而不会进行任何转义。
3)原始字符
>>> print('''"What's up?"
"I am fine"''')
"What's up?"
"I am fine"
项目准备
2. 构造字符串
有时字符串需要存储大段字符,不仅包括字符信息,还包括格式信息,如缩进、换行、空行等。Python提供了三重引号字符串。三重引号将保留所有字符串的格式信息。如字符串跨越多行,行与行之间的回车符、引号、制表符或者其他任何信息,都将保存下来。在三重引号中可以自由的使用单引号和双引号。
4)三重引号字符串
>>> print('''"What's up?"
"I am fine"''')
"What's up?"
"I am fine"
项目准备
3. 格式化字符串
字符串格式化涉及到两个概念:格式和格式化。
格式:以%开头。
格式化:运算符用%表示用对象代替格式串中的格式。
格式和格式化结合,得到一个任意形式的字符串。
1)字符串格式控制
项目准备
3. 格式化字符串
注意,格式化字符串由两部分组成,"内是格式串,"之后的%后面是符号表。
格式串中[ ]中的内容是可选内容。"内的%与后面的字符组成了格式符。常见格式串如表所示。
1)字符串格式控制
格式 说明
%c 格式化字符或编码
%s 格式化字符串
%d, %i 格式化整数
%u 格式化无符号整数
%% 字符%
%o 格式化八进制数
%x 格式化十六进制数
%f、%F 格式化浮点数,可指定小数位数
%e、%E 用科学计数法(基底e、基底E)格式化浮点数
%g、%G 根据值的大小采用科学计数法(基底e、基底E)或者浮点数形式格式化浮点数
项目准备
3. 格式化字符串
也可以一次格式化多个对象,示例代码如下:
1)字符串格式控制
>>> name='Jim'
>>> age=20
>>> 'My name is %s,I am %d years old.'%(name,age)
'My name is Jim,I am 18 years old.'
项目准备
3. 格式化字符串
可以通过设置图中m和n的值来控制格式化字符串的宽度和精度。
2)宽度和精度控制
>>> '%f'%3.141593 # 单独的%f默认保留6位小数
'3.141593'
>>> '%.2f'%3.141593 # 指定保留2位小数
'3.14'
>>> '%9.2f'%3.141593 # 宽度9位,保留2位小数,空位填空格
' 3. 14'
>>> '%09.2f'%3.141593 # 宽度9位,保留2位小数,空位填0
'000003.14'
>>> '%+09.2f'%3.141593 # 宽度9位,保留2位小数,正数加正号,空位填0
'+00003.14'
>>> '%-9.2f'%-3.141593 # 宽度9位,保留2位小数,空位填空格,左对齐输出
'-3.14 '
项目准备
3. 格式化字符串
3)进位制和科学计数法
>>> d=123456
>>> x='%o'%d # 转换为八进制串
>>> x
'361100'
>>> do='%#o'%d # 八进制时前添加0o
>>> do
'0o361100'
>>> dx='%x'%d # 转换为十六进制串
>>> dx
'1e240'
>>> dx_pre='%#x'%d # 16进制数前添加0x
>>> dx_pre
'0x1e240'
>>> de='%e'%d # 转换为科学计数法串,基底e
>>> de
'1.234560e+05'
>>> dE = '%E'%d #基底E
'1.234560E+05'
>>> d2 = 12345.678 # 浮点数
>>> dF = '%F'% d2
>>> dF
'12345.678000'
>>> df = '%f'% d2
>>> df
'12345.678000'
>>> dg = '%g'% d2 # 采用浮点数形式
>>> dg
'12345.7'
>>> dG = '%G'% d2 # 采用浮点数形式
>>> dG
'12345.7'
>>> dGe = '%.4G'% d2 # 采用科学计数法形式,基底E
>>> dGe
'1.235E+04'
项目准备
3. 格式化字符串
3)进位制和科学计数法
输出九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print("%d*%d=%-4d"%(i,j,i*j),end=" ")
print()
项目准备
3. 格式化字符串
format()方法用{}和:来代替%方式。
4)格式化字符串的format()方法
项目准备
3. 格式化字符串
format()的典型用法如下:
4)格式化字符串的format()方法
>>> '我叫{},今年{}岁'.format('李梅',20) # 按参数位置格式化
'我叫李梅,今年20岁'
>>> '我叫{1},今年{0}岁'.format(20,'李梅') # 按参数索引格式化
'我叫李梅,今年20岁'
>>> my=['李梅',20] # 列表做参数
>>> '我叫{},今年{}岁'.format(*my) # *列表名
'我叫李梅,今年20岁'
>>> '我叫{0[0]},今年{0[1]}岁'.format(my) # 列表索引
'我叫李梅,今年20岁'
>>> '我叫{name},今年{age}岁'.format(name='李梅',age=20) # 关键参数
'我叫李梅今年20岁'
>>> my={'name':'李梅','age': 20} # 字典
>>> '我叫{name},今年{age}岁'.format(**my) # **字典名
'我叫李梅,今年20岁'
项目准备
3. 格式化字符串
format()可以如%那样对进制和显示格式进行控制。
4)格式化字符串的format()方法
>>> '{0:.2f}'.format(1/3) # 保留两位小数
'0.33'
>>> '{0:b}'.format(8) # 二进制
'1000'
>>> '{0:o}'.format(8) # 八进制
'10'
>>> '{0:x}'.format(18) # 十六进制
'12'
>>> '{0:#x}'.format(10) # 十六进制前加0x
'0xa'
>>> '{:,}'.format(1234567890) # 千分位格式化
'1,234,567,890'
>>> '{0:*>10}'.format(18) # 右对齐
'********18'
>>> '{0:*<10}'.format(18) # 左对齐
'18********'
>>> '{0:*^10}'.format(18) # 居中对齐
'****18****'
>>> '{0:*=10}'.format(-18) # *放在-和18中间
'-*******18'
>>> '{0:_},{0:#x}'.format(9999) # _作为分隔符
'9_999,0x270f'
项目准备
3. 格式化字符串
Python提供了相较format()方法更简化的表达方法。
5)f前缀
>>> name='李梅'
>>> age=20
>>> f'我叫{name},今年{age}岁'
'我叫李梅,今年20岁'
项目准备
4. 截取字符串
截取字符串是常用的文本处理技巧。Python提供了两种字符串截取的方法:
索引str[index],只能取出单个字符串。
切片str[[start]:[end]:[step]],取出一片字符。
可以将字符串的索引和切片操作理解为与列表的相应操作一样。
项目准备
4. 截取字符串
>>> t='teacher'
>>> t[0]
't'
>>> t[-1]
'r'
>>> t[1:3] # 取出位置为1到位置为2的字符,不包括位置3的字符
'ea'
>>> t[:3] # 取出从头至位置为2的字符
'tea'
>>> t[-2:] # 取出从倒数第2个位置开始的所有字符
'er'
>>> t[:] # 取出全部字符
'teacher'
>>> t[::2] # 步长为2
'tahr'
>>> t[0]='s' # 字符串属于不可变序列类型,不支持字符串修改
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
t[0]='s'
TypeError: 'str' object does not support item assignment
项目准备
5. 字符串常用内置函数
如序列一样,Python也提供了很多用于操作字符串的内置函数,如:len()、ord()、chr()、max()、min()等。
>>> s='I am so happy today!'
>>> len(s) # 字符串长度
20
>>> max(s) # 最大字符
'y'
>>> min(s) # 最小字符
' '
>>> ord('I') # 获取该字符的Unicode码
73
>>> chr(73) # 把编码转换为对应的字符
'I'
>>> ord('兴')
20850
>>> chr(20850) # 获取编码对应字符
'好'
项目准备
6. 字符串常用方法
lower()
upper()
功能:lower()方法将大写字母转换为小写字母,其他字符不变,并返回新字符串。upper()方法将小写字母转换为大写字母,其他字符不变,并返回新字符串。
2)大写小写字母相关操作
>>> 'Hello'.lower()
'hello'
>>> 'Hello'.lower()
'HELLO'
项目准备
6. 字符串常用方法
center(width[, fillchar])
ljust(width[, fillchar])
rjust(width[, fillchar])
说明:width,指定宽度;fillchar,填充的字符,默认为空格。
功能:返回一个宽度为width的新字符串,原字符串居中(左对齐或右对齐)出现在新字符串中,如果width大于字符串长度,则使用fillchar进行填充。
1)填充字符串
>>> 'Hello'.center(8) # 居中对齐,以空格填充
' Hello '
>>> ' Hello '.center(8,"*") # 居中对齐,以*填充
'* Hello**'
>>> ' Hello'.ljust(8,"!") # 右对齐,以!填充
' Hello!!!'
>>> ' Hello'.rjust(8,"-") # 左对齐,以-填充
'--- Hello'
项目准备
6. 字符串常用方法
capitalize()
title()
swapcase()
功能:capitalize()方法将字符串首字母转换为大写形式,其他字母转换为小写形式。title()方法将每个单词的首字母转换为大写形式,其他部分的字母转换为小写形式。swapcase()字符将大小写互换。均返回新字符串,原字符串对象不做任何修改。
2)大写小写字母相关操作
>>> 'happy spring festival!'. capitalize ()
'Happy spring festival!'
>>> 'happy spring festival!'. capitalize ()
'Happy Spring Festival!'
>>> 'happy spring festival!'. capitalize ()
'HAPPY SPRING FESTIVAL!'
项目准备
6. 字符串常用方法
islower();
isupper();
isdigit()。
功能:测试字符串是否为小写、大写、数字。如果是,则返回True;否则返回False。
2)大写小写字母相关操作
>>> s='hello'
>>> s.islower()
True
>>> s.isupper()
False
>>> s='7890'
>>> s.isdigit()
True
>>> s='78.90' # 小数点不是数字
>>> s.isdigit()
False
项目准备
6. 字符串常用方法
find(sub[, start[, end]])
rfind(sub[, start[, end]])
说明:sub:字符串(子串);start:开始位置;end:结束位置。查找范围start开始,end结束,不包括end。
功能:在一个较长的字符串S中,在[start,end)范围内查找并返回子串sub首次出现的位置索引,如果没有找到则返回-1。默认范围是整个字符串。其中find()方法从左往右查找,rfind()方法从右往左查找。
3)查找与替换字符串
>>> 'happy spring festival!'. find ('happy')
0
>>> 'happy spring festival!'. find ('i', 6)
9
>>> 'happy spring festival!'. rfind ('i', 5,18)
17
>>> 'happy spring festival!'. rfind ('H', 5,18)
-1
项目准备
6. 字符串常用方法
index(sub[, start[, end]])
rindex(sub[, start[, end]])
功能:在一个较长的字符串S中,查找并返回在[start,end)范围内子串sub首次出现的位置索引,如果不存在则抛出异常。默认范围是整个字符串。其中index()方法从左往右查找,rindex()方法从右往左查找。
3)查找与替换字符串
>>> 'happy spring festival!'. index('happy')
0
>>> 'happy spring festival!'. index('i', 6)
9
>>> 'happy spring festival!'. rindex('i', 5,18)
17
>>> 'happy spring festival!'. rindex('H', 5,18)
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
'happy spring festival!'.index(' H', 5,18)
ValueError: substring not found
项目准备
6. 字符串常用方法
count(sub[, start[, end]])
功能:在一个较长的字符串S中,查找并返回[start,end)范围内子串sub出现的次数,如果不存在则返回0。默认范围是整个字符串。
3)查找与替换字符串
>>> 'happy spring festival!'. count('i')
2
项目准备
6. 字符串常用方法
replace(old,new,count=-1)
功能:查找字符串中old子串并用new子串来替换。参数count默认值为-1,表示替换所有匹配项,否则最多替换count次。返回替换后的新字符串。
3)查找与替换字符串
>>> 'happy spring festival!'. replace('s', 'S')
'happy Spring feStival!'
项目准备
6. 字符串常用方法
maketrans()
translate()
功能:maketrans()方法生成字符映射表,translate()方法是根据字符映射表替换字符。这两种方法联合起来使用可以一次替换多个字符。
3)查找与替换字符串
>>> tlst=''.maketrans('ygl!','1234’)
#两个序列中的元素按照次序一一对应用于替换
>>> 'happy spring festival!'. translate(tlst)
'happ1 sprin2 festiva34'
项目准备
6. 字符串常用方法
strip()
功能:去除字符串两侧的空白字符或指定字符,并返回新字符串。
3)查找与替换字符串
>>> ' happy spring festival! '. strip()
'happy spring festival!'
项目准备
6. 字符串常用方法
split(sub)
功能:以指定字符sub为分隔符,从左往右将字符串分割开来,并将分割后的结果组成列表返回。如果不指定分隔符,实际上表示以任何空白字符(包括连续出现的)作为分隔符。空白字符包括空格、换行符、制表符等。如果字符串中的某种字符出现0次或多次,可以利用split()方法,根据该字符把字符串分离成多个子串组成的列表。
4)分割与连接字符串
>>> 'happy spring festival!'. split()
['happy', 'spring', 'festival!']
>>> 'happy spring festival!'. split('s')
['happy ', 'pring fe', 'tival!']
项目准备
6. 字符串常用方法
join(sub)
功能:join()方法可用来连接序列中的元素,并在两个元素之间插入指定字符,返回一个字符串。
split()和join()互为逆方法。
4)分割与连接字符串
>>> '*'.join('happy spring festival!')
# 字符串序列中,每个字符为一个元素
'h*a*p*p*y* *s*p*r*i*n*g* *f*e*s*t*i*v*a*l*!'
>>> '*'.join(['happy', 'spring', 'festival!'])
# 列表中,每个字符为一个元素
'happy*spring*festival!
项目准备
7. string模块
字符串string模块定义了Formatter类、Template类、capwords函数和常量,熟悉string模块可以简化某些字符串的操作。可以通过如下命令来查看string类的内容。
>>> import string
>>> help(string)
项目准备
7. string模块
string类用法举例如下:
>>> import string
>>>s='happy spring festival!'
>>>s_cap = string.capwords(s) # capwords()函数把字符串中每一个英语单词首字母变成大
写,其他字母变成小写,返回新字符串。
>>>print(s_cap)
'Happy Spring Festival!'
项目准备
8. 正则表达式
正则表达式是一个特殊的字符序列,利用事先定义好的一些特定字符以及它们的组合组成一个“规则”,检查一个字符串是否与这种规则匹配来实现对字符的过滤或匹配。正则表达式是字符串处理的有力工具,但是并不是Python独有的,其他语言也有。
1)正则表达式定义
项目准备
8. 正则表达式
Python中,re模块提供了正则表达式操作所需要的功能。re模块中findall()方法以列表的形式返回所有能匹配的子串,如果没有找到匹配的,则返回空列表。
2)re模块
>>> import re
>>> s=r'xyz'
>>> re.findall(s,'xxyxxy') #无匹配
[]
>>> re.findall(s,'xxyzxxyz') #两处匹配
['xyz', 'xyz']
项目准备
8. 正则表达式
大多数字母和字符一般都会和自身匹配。如果在字符串前面加了r,表示对字符串不进行转义。有些字符比较特殊,它们和自身并不匹配,而是表明应和一些特殊的东西匹配,或者会影响重复次数。这些特殊的字符我们称之为元字符。
3)元字符
项目准备
8. 正则表达式
(1)“.”:表示除换行符以外的任意字符。、
说明:元字符“\S”,表示不是空白符的任意字符,含义与“.”类似。
3)元字符
>>> import re
>>> s='happy spring festival!'
>>> re.findall(r'.',s) #匹配除换行符以外的任意字符
['h', 'a', 'p', 'p', 'y', ' ', 's', 'p', 'r', 'i', 'n', 'g', ' ', 'f', 'e', 's', 't', 'i', 'v', 'a', 'l', '!']
>>> re.findall(r's.',s) #匹配s后面跟除换行符以外的任意字符的形式
['sp', 'st']
>>> re.findall(r'i\S',s) #匹配i后面跟不是空白符的任意字符的形式
['sp', 'st']
项目准备
8. 正则表达式
(2)“[]”:指定字符集。
指定一个用于匹配的字符集,例如:[xyz]、[A-Z]、[0-9]。方括号内的“^”表示补集,匹配不在区间范围内的字符,例如:[^A]表示除A以外的字符。
注意,元字符在方括号中不起作用,例如:[xyz$]和[x.]中元字符‘$’和‘.’都不起作用。
3)元字符
>>> import re
>>> s='happy spring festival!'
>>> re.findall(r'i[nv]',s) # 匹配m后跟i或者w再跟t形式
['in', 'iv']
>>> re.findall(r'i[.]',s) # 元字符“.”放在[]内,不起作用
[]
>>> s='0a12a3a567a8ab'
>>> re.findall(r'a[0123456789]a',s)
['a3a', 'a8a']
>>> re.findall(r'a[0-9]a',s) # [0-9]与[0123456789]等价
['a3a', 'a8a']
>>> re.findall(r'a[^3]a',s) # x后跟不为3的字符再跟x
['a8a']
项目准备
8. 正则表达式
(3)“^”:匹配行首,匹配以^后面的字符开头的字符串。
注意,“^”根据其是否在[]中,有不同的含义。
3)元字符
>>> import re
>>> s=' happy happy happy spring festival!'
>>> re.findall(r' happy',s)
[' happy', 'happy', 'happy']
>>> re.findall(r'^happy',s)
['happy']
项目准备
8. 正则表达式
(4)“$”:匹配行尾,匹配以$之前的字符结束的字符串。
3)元字符
>>> import re
>>> s=' happy happy happy spring festival happy!'
>>> re.findall(r'happy$',s)
['happy']
项目准备
8. 正则表达式
(5)“\”:反斜杠后面可以加不同的字符以表示不同的特殊意义。
\b匹配单词头或单词尾;
\B与\b相反,匹配非单词头或单词尾;
\d匹配任何十进制数;相当于[0-9];
\D与\d相反,匹配任何非数字字符,相当于[^0-9];
\s匹配任何空白字符,相当于[\t
\r\f\v];
\S与\s相反,匹配任何非空白字符,相当于[^\t
\r\f\v];
\w匹配任何字母、数字或下画线字符,相当于[a-zA-Z0-9_];
\W与\w相反,匹配任何非字母、数字和下画线字符,相当于[^a-zA-Z0-9_];
也可以用于取消所有的元字符:\\、\[。
这些特殊字符都可以包含在[]中。如:[\s,.]将匹配任何空白字符、","或"."。
3)元字符
项目准备
8. 正则表达式
3)元字符
>>> import re
>>> s='0a12a3a567a8ab'
>>> re.findall(r'[0-9]',s)
['0', '1', '2', '3', '5', '6', '7', '8']
>>> re.findall(r'\d',s)
['0', '1', '2', '3', '5', '6', '7', '8']
>>> re.findall(r'[x\d]',s) #匹配字母“a”或数字
['0', 'a', '1', '2', 'a', '3', 'a', '5', '6', '7', 'a', '8', 'a']
项目准备
8. 正则表达式
(6)“*”:匹配位于*之前的字符或子模式的0次或多次出现。
3)元字符
>>> import re
>>> s='h ha haaaaa haaaaaph'
>>> re.findall(r'ha*',s) # h后面跟重复0到多次的a
['h', 'ha', 'haaaaa', 'haaaaa', 'h']
项目准备
8. 正则表达式
(7)“+”:匹配位于+之前的字符或子模式的1次或多次出现。
3)元字符
>>> import re
>>> s='h ha haaaaa haaaaaph'
>>> re.findall(r'ha+',s) # a后面跟重复1到多次的b,贪心模式
['ha', 'haaaaa', 'haaaaa']
项目准备
8. 正则表达式
(8)“?”:匹配位于?之前的0个或1个字符。
当“?”紧随其他限定符(*、+、{n}、{n,}、{n,m})之后时,匹配模式是“非贪心的”。“非贪心的”模式匹配搜索到尽可能短的字符串,而默认的“贪心的”模式匹配搜索到的、尽可能长的字符串。上一个例子就是贪心的,下面展示一下非贪心的场景。
3)元字符
>>> import re
>>> s='h ha haaaaa haaaaaph'
>>> re.findall(r'ha+?',s) # 最小模式、非贪心模式
['ha', ' ha', ' ha']
项目准备
8. 正则表达式
(9)“{m,n}”:表示至少有m个重复,至多有n个重复。m,n均为十进制数
忽略m表示0个重复,忽略n表示无穷多个重复。{0,}等同于*;{1,}等同于+;{0,1}与?相同。但是如果可以的话,最好使用*、+、或?。
3)元字符
>>> import re
>>> s='h a ahhhhah'
>>> re.findall(r'h{1,3}',s)
['h', 'hhh', 'h', 'h']
>>> s='010-44618bba,010-33619876,020-87654321,010-987654321'
>>> re.findall(r'010-\d{8}',s)
['010-33619876', '010-98765432']
>>> re.findall(r'\b010-\d{8}\b',s) #\b表示匹配字符串的头或尾
['010-33619876']
项目准备
8. 正则表达式
re模块中的split方法用于将字符串按与正则表达式匹配的子串分割。re.split函数的语法格式如下:
4)re.split方法
re.split(pattern, string, maxsplit=0, flags=0)
说明:
pattern是正则表达式;
string是要分割的字符串;
maxsplit是最大分割次数,默认为0表示不限制分割次数;
flags与re.match等函数中的flags参数含义相同。
项目准备
8. 正则表达式
re模块的sub函数用于替换字符串中与正则表达式匹配的子串。re.sub函数的语法格式为:
5)re.sub方法
re.sub(pattern, repl, string, count=0, flags=0)
说明:
pattern是正则表达式;
repl是要将匹配子串替换成的字符串;
string是待做替换操作的字符串;
count是最大替换次数,默认为0表示不限制替换次数(即将所有符合正则表达式的子串都替换成repl);
flags与re.match等函数中的flags参数含义相同。
项目准备
9. 网络爬虫基本概念
网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。
目录 | CONTENT
1
项目介绍
2
项目目标
3
项目准备
4
项目实施
任务背景
大数据时代,数据就是矿藏,如何发现、收集、挖掘数据,显然是一项重要的事情。通过网络爬虫,可以快速收集大量的数据用于处理或分析。网络爬虫,是一种按照一定的规则,自动地抓取网络信息的程序或者脚本。
本项目首先基于Windows环境下的Tomcat软件发布本地网站,然后使用Python编写的爬虫对本地网站内容进行爬取。在实现爬虫时,使用了Urllib2模块来模拟浏览器访问网页。
项目实施
任务11-1 Python爬虫
任务需求
搭建一个本地网页,利用python爬虫爬取本地网页上的文字内容。
项目实施
任务11-1 Python爬虫
任务分析
项目实施
任务11-1 Python爬虫
任务步骤
项目实施
任务11-1 Python爬虫
(1)借用Pycharm工具,建立Python3项目
(2)搭建一个本地网页
(3)利用python爬虫爬取本地网页上的文字内容
任务效果
项目实施
任务11-1 Python爬虫
任务实施
项目实施
任务11-1 Python爬虫
将本地的网站tomcat压缩包解压到任意目录下(本实验解压目录为D盘)
任务实施
项目实施
任务11-1 Python爬虫
进入到tomcat/bin文件夹中
任务实施
项目实施
任务11-1 Python爬虫
鼠标左键双击startup.bat启动tomca
任务实施
项目实施
任务11-1 Python爬虫
出现如图页面表示启动成功
任务实施
项目实施
任务11-1 Python爬虫
打开的浏览器地址栏中输入网页地址,查看网页内容,如图所示。
[Command 001]:
http://localhost:8080/liarbry/html/books-1.html
任务实施
项目实施
任务11-1 Python爬虫
从本步骤开始,使用Python建立爬虫。
用鼠标双击桌面“Pycharm”图标,打开Pycharm工具,依次选择主菜单“File”->“New Project…”选项,在弹出的窗口中Location对应的文本框中输入项目名project,单击“Create”按钮,完成项目的创建。
任务实施
项目实施
任务11-1 Python爬虫
如果是第1次打开此工具会弹出“Welcome to PyCharm Community Edition”窗口,鼠标单击“Do not show again”,下次再打开工具时就不会弹出此窗口。然后选择“Create New Project”,在弹出的窗口中Location对应的文本框中输入项目名“project”,单击“Create”按钮,完成项目的创建。
任务实施
项目实施
任务11-1 Python爬虫
建立包名“experiment”,用于写清洗Python程序。具体做法:选中新建立的项目“project”,右击,在弹出的快捷菜单中选择“New”->“Python Package”
任务实施
项目实施
任务11-1 Python爬虫
在弹出的New Package窗口中的文本框内,输入要建立的包名(用户可自定义)“experiment”,单击“OK”按钮,完成包名的创建
任务实施
项目实施
任务11-1 Python爬虫
此时在窗口左侧的窗口中的“project”项目下可以看到新建立“experiment”程序包,在该包下写实验相关的Python程序
任务实施
项目实施
任务11-1 Python爬虫
设置统一的编码模式,使新生成的文件支持中文,统一设置utf-8编码。单击“File”->“settings”->“Editor”->“File and Code Templates”->“Python Script”选项。在Python Script对应的文本模式中输入具体编码设置,单击“OK”按钮,完成设置
[Code 001]:
#!/usr/bin/python
# -*- coding:utf-8 -*-
任务实施
项目实施
任务11-1 Python爬虫
下面开始编写Python3程序,实现爬取网页数据的功能。
为了实现爬取http://localhost:8080/liarbry/html/books-1.html网页的数据,建立python文件Spider.py编写程序。具体做法:选中包名“experiment”,右击,在弹出的快捷菜单中选择“New”->“Python File”,
任务实施
项目实施
任务11-1 Python爬虫
在弹出的窗口中,属性值Name对应的文本框中输入新建立的文件的名字“Spider”,单击“OK”按钮,完成文件的创建
任务实施
项目实施
任务11-1 Python爬虫
在新建立的Spider.py文件中编写代码。具体代码如下。在弹出的窗口中,属性值Name对应的文本框中输入新建立的文件的名字“Spider”,单击“OK”按钮,完成文件的创建。
#!/usr/bin/python
# -*- coding:utf-8 -*-
# 加载模块
import requests
import bs4
# 定义待爬取网页连接
url = 'http://localhost:8080/liarbry/html/books-3.html'
# 获取网页源码
response = requests.get(url)
# 使用bs4解析网页
content = bs4.BeautifulSoup(response.content.decode("utf-8"), "lxml")
# 找到节点<a>的信息
element = content.find_all( name='a')
# 打开文本文件并写入信息
f1 = open('urls.txt', 'w')
f1.write(str(element).strip())
f1.close()
# 查找第三个节点<a>中的第0个内容
element = content.find_all('a')[3].contents[0]
print(element)
# 查找href为特定链接的节点
element = content.find_all( href='http://books.toscrape.com/catalogue/category/books/sports-and-games_17/index.html')
print(element)
# 查找属性id为default的节点
element = content.find_all( id='default')
f2 = open('body.txt', 'w')
f2.write(str(element).strip())
f2.close()
任务实施
项目实施
任务11-1 Python爬虫
运行结果
任务实施
项目实施
任务11-1 Python爬虫
查看爬取的urls.txt内容(内容过多,给出部分数据截图)
任务实施
项目实施
任务11-1 Python爬虫
查看爬取的body.txt内容(内容过多,给出部分数据截图)
课后练习与技能训练
一、填空题
练习
1.Python中,创建字符串时,可以使用单引号、 和三引号。
2.Python中,使用字符串的 方法可以按照指定的分隔符对字符串进行切割,返回由切割结果组成的列表。
3.可以利用运算符+连接两个字符串,也可以使用 方法将序列中的元素以指定的字符连接成一个新的字符串。
课后练习与技能训练
一、填空题
练习
4.Python中正则表达式中的普通字符需要做精确匹配,而特殊字符指定的匹配模式则对应了用于 匹配的规则。
5.Python中正则表达式的特殊序列是由 和一个字符构成。
6.使用Python提供的 模块,可以实现基于正则表达式的模糊匹配。
7. 函数用于将一个字符串形式的正则表达式编译成一个正则表达式对象,供 match、search以及其他一些函数使用。
课后练习与技能训练
一、填空题
练习
8.re模块中的match函数用于对字符串开头的若干字符进行正则表达式的匹配。匹配成功,返回一个 ;匹配失败,返回 。
9.re模块中的finditer函数与re.findall函数功能都是用于在字符串中找到所有与正则表达式匹配的子串,区别在于re.findall函数返回 形式的结果,而re.finditer返回 形式的结果。
10.re模块中的 函数用于将字符串按与正则表达式匹配的子串分割。
课后练习与技能训练
二、选择题
练习
1.已知s1=”I “am a student.”,s2=’I \’am a student’,则print(s1,s2)的输出结果为() I 'am a student. I 'am a student
I “am a student. I 'am a student
I “am a student. I \'am a student
程序报错
课后练习与技能训练
二、选择题
练习
2.下列说法错误的是()
A.find方法是在指定检索范围中按照从左至右的顺序检索,找到子串第一次出现的位置
B.rfind方法在指定检索范围中按照从右至左的顺序检索,找到子串第一次出现的位置
C.index与find作用相同,rindex与rfind作用相同,只是find和rfind在检索不到字符串时返回-1,而index和rindex会引发ValueError异常
D.index与find作用相同,rindex与rfind作用相同,只是find和rfind找到一个就返回,而index和rindex会检索到所有的子串
课后练习与技能训练
二、选择题
练习
3.下列关于replace方法str.replace(old, new[, max])的说法错误的是()
A.使用字符串中的replace方法可以将字符串中的指定子串替换成其他内容
B. str是要做替换操作的字符串,old和new分别是要替换的子串和替换成的字符串
C.max是最多替换的子串数量,如果不指定max参数则只替换第一个满足条件的子串
D.replace方法返回替换后的字符串
课后练习与技能训练
二、选择题
练习
4.print(len("中国\"china"))的输出结果是()
A.7
B.8
C.9
D.1
课后练习与技能训练
二、选择题
练习
5.下列匹配模式叙述错误的是()
^用于匹配字符串开头的若干字符
*用于匹配前一个模式0次或多次
?用于匹配前一个模式0次或1次
A|B表示同时匹配模式A和模式B
课后练习与技能训练
二、选择题
练习
6.关于正则表达式特殊序列叙述错误的是()
A.\A匹配字符串开头的若干字符,功能同^
B.\d匹配任一数字字符,等价于[0-9]
C.\S匹配任一空白字符
D.\D与\d作用相反,匹配任一非数字字符,等价于[^0-9]
课后练习与技能训练
三、简答题
练习
1.写出下面程序的运行结果。
print("ad">"abcd")
print("AD">"abcd")
print("AD">"ADC")
print("tianjin">"beijing")
print("天津">"北京")
课后练习与技能训练
三、简答题
练习
2.写出下面程序的运行结果。
s1="I am a student."
s2="C++90分Python88分Java85分"
s3="I am a student.
I like programming.
"
print(s1.split())
print(s2.split("分"))
print(s2.split("分",2))
print(s3.splitlines())
课后练习与技能训练
三、简答题
练习
3.写出下面程序的运行结果。
str=" a b c "
print("123"+str.strip()+"456")
print("123"+str.lstrip()+"456")
print("123"+str.rstrip()+"456")
课后练习与技能训练
三、简答题
练习
4.下面程序从键盘输入一个字符串,然后将其中的大写字母转换为小写字母,小写字母转换为大写字母,其他字符不变,请将程序填写完整。
str = input("请输入一个字符串")
ns=''
for c in str:
if c>='A' and c<='Z':
ns+=
elif
ns+=c.upper()
else:
print(ns)
课后练习与技能训练
三、简答题
练习
5.写出下面程序的运行结果。
n,f=34,56.78
print("%d,%o,%x"%(n,n,n))
print("%f,%e"%(f,f))
r=5
s=3.14*r*r
s1="半径为{0}的圆面积为{1}"
s2="半径为{radius}的圆面积为{area}"
print(s1.format(r,s))
print(s2.format(area=s,radius=r))
课后练习与技能训练
三、简答题
练习
6.写出下面程序的运行结果。
import re
pattern=re.compile(r'Student', re.I) #生成正则表达式对象
r1=pattern.match('Students study programming')
r2=pattern.match('I am a student!',3)
r3=pattern.match('I am a student!',7)
r4=re.search(r'Student','I am a student',re.I)
r5=re.match(r'Student','I am a student',re.I)
print(r1)
print(r2)
print(r3)
print(r4)
print(r5)
课后练习与技能训练
三、简答题
练习
7.写出下面程序的运行结果。
import re
str='''sno:#1810101#,name:#李晓明#,age:#19#,major:#计算机#
sno:#1810102#,name:#马红#,age:#20#,major:#数学#'''
rlt=re.search(r'sno:#([\s\S]*?)#[\s\S]*?major:#([\s\S]*?)#', str, re.I)
if rlt: #判断是否有匹配结果
print('匹配到的整个字符串:', rlt.group())
print('sno:%s, startpos:%d, endpos:%d'%(rlt.group(1), rlt.start(1), rlt.end(1)))
print('major:%s, startpos:%d, endpos:%d'%(rlt.group(2), rlt.start(2), rlt.end(2)))
print('所有分组匹配结果:', rlt.groups())
else:
print('未找到匹配信息')
课后练习与技能训练
三、简答题
练习
8.写出下面程序的运行结果。
import re
html='''%abc%%def%python(ghi)'''
content=re.sub(r'%[\s\S]*%', '&', html)
content=content.strip()
print('替换之后的内容为: ', content)
content2=re.subn(r'%[\s\S]*%', '&', html)
print('替换之后的内容及替换次数为: ', content2)
$$