一:网页数据的种类介绍
1.网页数据的类别划分
从前面 17K 小说网抓取书架信息中了解到,有些数据信息并不是直接存放在 Html 页面中,而是按照一定规则单独存放起来的,这种数据就是结构化数据。
爬虫中网页数据结构划分主要有以下几个部分:
1.文本数据:包括网页标题,正文内容,链接,标签,元数据等。
2.多媒体数据:包括图片,音频,视频等媒体资源。
3.结构数据:包括HTML,XML,JSON等结构化数据格式,用于描述网页文本和图像等的结构和内容布局。
4.动态数据:包括JavaScript脚本生成的动态数据,例如AJAX请求获取的数据等。
5.元数据:包括网页的URL,网站名称,网页描述等元数据信息。这些信息对于搜索引擎优化和网站分析非常重要。
以上五种数据结构是爬虫获取网页数据的主要对象,通过分析这些结构,可以获得丰富的网页信息。
爬虫中文本数据的种类划分:
结构化数据:
基本介绍:是一种按照一定格式所组成的数据集合,筛选数据时只需要了解字段和格式即可。
涉及种类:json,xml等
处理方式:Jsonpath
非结构化数据:
基本介绍:是指没有固定格式或者结构的数据,这些数据通常是自由格式的,需要单独进行筛选。
涉及种类:HTML,字符串等
处理方式:正则表达式,xpath
2.正则表达式的介绍
正则表达式是一种特殊的文本匹配模式,用于检查给定文本中是否存在与特定模式匹配的字符串。Python中的re模块是一个内置的正则表达式工具,用于处理各种正则表达式操作。
Python正则表达式语法包括:
1.字符匹配:通过直接匹配字符或字符集合来识别字符串;
2.重复语法:用来定义重复出现的模式,包括? + *等;
3.分组语法:用来将模式分组,以便进行更复杂的匹配;
4.位置匹配:用来定义字符串的边界,并指定匹配的位置。
正则表达式是Python中非常有用的工具,可以帮助程序员在处理字符串时更加灵活和高效
正则表达式相关的字符
元字符 | 匹配内容 |
---|---|
. | 匹配除了换行符以外的任意字符 |
\w | 匹配所有的普通字符(数字,字母或下划线) |
\d | 匹配数字 |
\s | 匹配任意空白符 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始位置 |
$ | 匹配字符串的结尾位置 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a|b | 匹配字符 a 或字符 b |
() | 正则表达式分组所用符号,提升括号内的优先级 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中字符的所有字符 |
* | 重复零次或者更多次 |
+ | 重复一次或者更多次 |
? | 重复0次或者一次 |
{n} | 重复n次 |
{n,} | 重复n次或者更多次 |
{n,m} | 重复n到m次 |
正则表达式
正则语法 | 待匹配字符 | 匹配结果 | 功能说明 |
---|---|---|---|
[0123456789] | 8 | True | 字符组里的任意一个字符和待匹配字符相同就视为可以匹配 |
[0123456789] | a | False | 由于字符组中没有 “a” 字符,所以不能匹配 |
[0-9] | 7 | True | 也可以用-表示范围,[0-9] 就和 [0123456789] 是一个意思 |
[a-z] | s | True | 同样的如果要匹配所有的小写字母,直接用 [a-z] 就可以表示 |
[A-Z] | B | True | [A-Z] 就表示所有的大写字母 |
[0-9a-fA-F] | e | True | 可以匹配数字,大小写形式的 a~f,用来验证十六进制字符 |
3.正则表达式的使用
常用的正则匹配函数有:
- re.search(pattern, string, flags=0):在字符串中搜索匹配指定正则表达式的第一个位置,返回匹配对象,否则返回None。
- re.match(pattern, string, flags=0):从字符串的开头开始匹配正则表达式,返回匹配对象,否则返回None。
- re.findall(pattern, string, flags=0):搜索字符串中所有匹配正则表达式的结果,返回一个列表,如果没有匹配到则返回空列表。
PS:
flags 是可选参数,用来指定额外的匹配标志。例如,指定 re.IGNORECASE 可以忽略大小写进行匹配
匹配手机号码
手机号码的格式为11位数字,以1开头
import re
phone_number = '13812345678'
pattern = '^1\d{10}$'
result = re.match(pattern, phone_number)
if result:
print('手机号码格式正确')
else:
print('手机号码格式错误')
匹配邮箱地址
邮箱地址由用户名和域名组成
用户名由数字,字母,下划线和点号组成
域名由数字,字母,点号和减号组成
import re
email = 'test@163.com'
pattern = '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
result = re.match(pattern, email)
if result:
print('邮箱格式正确')
else:
print('邮箱格式错误')
4.筛选非结构化数据
使用Python正则表达式筛选网页数据
目标网址:https://www.huya.com/g/2168
题目需求:获取主播封面图片的链接
import re
import time
import requests
# 1、定义请求头
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
# 2、发送请求获取网页内容
url = "https://www.huya.com/g/2168"
# 3、发送请求
response = requests.get(url, headers=headers)
# 4、使用正则表达式从网页内容中提取图片链接
# <img class="pic" -> 匹配<img>标签中含有 class="pic" 的部分。
# .*? -> 匹配任意字符(除换行符外)0次或多次,非贪婪匹配(尽可能少匹配)。
# data-original=" -> 匹配 data-original=" 字符串。
# (.*?) -> 括号内的部分表示要提取的内容,即图片URL。
# " .*?> -> 匹配以 " 结尾并且后面可能有其他属性的部分。
url_re = r'<img class="pic" .*? data-original="(.*?)" .*?>'
image_urls = re.findall(url_re, response.text)
# print(image_urls)
# 使用正则表达式从网页内容中提取主播名称
title_re = r'<img class="pic" .*? data-original=".*?" .*? title="(.*?)"/>'
image_title = re.findall(title_re, response.text)
# print(image_title)
# 5、判断当前路径下是否不存在images文件夹
if not os.path.exists('images'):
# 如果images文件夹不存在就创建images文件夹
os.mkdir('images')
# 6、遍历图片的链接和名称
for url, title in zip(image_urls, image_title):
# 7、切割图片链接后的内容, 从而得到原图
# url = url.replace('?imageview/0/w/338/h/190/blur/1', '') # 有些链接的后缀不一
样
url = url.split('?')[0]
# 8、判断链接前6位是不是https,如果不是则添加协议头:
if url[0:6] != 'https:':
url = 'https:' + url
print(url)
# 9、请求每张图片的链接,从而获取图片的数据
response = requests.get(url, headers=headers)
# 10、将图片数据保存到电脑上
with open(f'./images/{title}.jpg', 'wb') as file:
file.write(response.content)
print(f'{title}下载完毕。。。。')
# 循环执行一次休眠1秒,从而降低请求频率
time.sleep(1)