爬虫
网页
- 获取网络数据 (后裔采集器、requests、selenium)
- 数据解析 (正则表达式、bs4(基于css选择器的解析器)、lxml(基于Xpath的解析器))
- 保存数据 (csv)
爬虫步骤:
确定目标数据(需要获取的数据)---->找网页(哪些网站的哪些页面可以提供数据) ----->获取数据---->解析数据------>保存数据
requests
# 1.请求网络数据
response = requests.get('https://cd.zu.ke.com/zufang')
# 2. 设置解码方式(乱码的时候需要设置-一定要在获取请求结果之前设置)
response.encoding = 'utf-8'
# 3. 获取请求结果
# 1)获取请求结果对应的文本数据 -- 爬网页
print(response.text)
# 2)获取二进制格式的请求结果 -- 下载图片、视频、音频
print(response.content)
"""
保存图片数据到本地文件
"""
with open('地址', 'wb') as f:
f.write(response.content)
# 3)获取请求结果json转换的结果 -- json接口
print(response.json())
# 添加header :a.浏览器伪装(user—agent)、b.免密登录(cookie)、c.设置代理(proxies)
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
response = requests.get('https://movie.douban.com/top250',headers = headers)
os
import os
# os.mkdir(文件夹路径) 在指定的位置创建文件夹
# os.path.exists(文件夹路径) 判断文件夹是否存在
正则表达式(让复杂的字符串变得简单的工具)
from re inport fullmatch,findall,search,match,finditer,split,sub
# 1. re模块 提供了python 中所有和正则相关的函数
#1.) fullmatch(正则表达式,字符串) 判断整个字符串是否满足正则表达式所描述的规则,匹配成功返回匹配对象,失败返回None
#2) findall(正则,字符串) 提取字符串中所有满足正则表达式的字符串,默认返回一个列表,列表中的元素是所有匹配到的字串(自动捕获)
#3) search(正则,字符串) 匹配字符串中第一个满足正则表达式的字符串,匹配成功返回匹配对象,失败返回None
#4)split(正则,字符串,[N]) 将字符串中满足正则的前N个子串作为切割点进行切割
#5)sub(正则,字符串1,字符串2,[N]) 将字符串2中满足正则的前N个子串都替换成字符串1
#6)finditer(正则,字符串) 获取字符串中所有满足正则表达式的字符串,返回一个迭代器,迭代器中的元素是匹配对象
#7) match(正则,字符串) 匹配字符串开头
# python中表达式一个正则表达式一般用r字符串
# 2. 正则符号
#1)普通符号 在正则表达式中表示符号本身的符号
#2) . 匹配任意一个字符
#3) \d 匹配任意一个数字
#4) \s 匹配任意一个空白字符
# 空白字符: 空格(' ')、换行('\n')、水平制表符('\t')
#5) \w 匹配任意一个字母、数字、下划线或者中文
#6) \D、\S、\W 分别和\d、\s、\w 的功能相反
#7) [字符集] 匹配在字符集中的任意一个字符
result = fullmatch(r'abc[M9你]123','abcM123') #
#[^字符集] 匹配不在这个字符集中的任意一个字符
# 匹配类符号
#1) * 任意次数(0、1、....次)
"""
a* a出现任意多次
\d* 任意多个数字
[ad]*
"""
#2) + 一次或者多次
#3) ? 零次或者一次
#4) {}
"""
{N} N次
{M,N} M到N次
{M,} 至少M次
{,N} 最多N次
"""
# 贪婪和非贪婪模式
"""
在匹配次数不确定的时候,如果有多种次数都可以匹配成功,贪婪取最多的次数,非贪婪取最少的哪个次数
贪婪模式:+、?、*、{M,N}、{M,}、{,N}
非贪婪模式:+?、??、*?、{M,N}?
"""
# 分组和分支
#1) 分组: ()
"""
正则表达式中可以用()将部分内容括起来表示一个整体;括号括起来的部分就是一个分组。
a. 整体操作的时候需要分组
# '23M'、'12M23N'
result = re.fullmatch(r'(\d\d[A-Z])+','23M53L65P')
b. 重复匹配 : 正则中可以通过\M来重复它前面第M个分组匹配的结果
# '12B12'、'34G34'、'44G44'
result = re.fullmatch(r'(\d\d)[A-Z]\1','12M12')
c. 捕获 : 提取分组匹配到的结果(捕获分为自动捕获和手动捕获)
findall 在正则表达式中有分组的时候,会自动提取正则匹配结果中分组匹配到的内容
message = 'q文档234n1324ew23素不相22dwe'
result= re.findall(r'[\u4e00-\u9fa5](\d+)',message)
print(result)
search(手动捕获)
result = re.search(r'[\u4e00-\u9fa5](\d+)',message)
print(result.group(1))
"""
#2) 分支: 先用正则1进行匹配,匹配失败用正则2进行匹配....
result = fullmatch(r'\d{3}|[a-z]{2}','mn')
# 转义符号:在本身具有特殊功能或者特殊意义的符号前加\,让特殊符号变成普通
result = re.fullmatch(r'\d\d\.\d\d','23.21')
result = re.fullmatch(r'\(\d\d\),'(23)')
# 单独存在有特殊意义的符号在[]中它的功能会消失
result = fullmatch(r'\d[+.?()]\d','2+3')
# 忽略大小写: (?i)
print(re.fullmatch(r'(?i)abc','Abc'))
print(re.fullmatch(r'(?i)abc','ABC'))
# 单行匹配: (?s)
# 多行匹配(默认): . 不能和换行符进行匹配
# 单行匹配:. 可以和换行符进行匹配
print(re.fullmatch(r'abc.123','abc\n123')) #None
print(re.fullmatch(r'(?s)abc.123','abc\n123')) #