每天30分钟 一起来学习爬虫——day9(解析数据 之 正则表达式,实例:笑话大全图片爬取)

常用正则表达式

单个字符:

符号 含义
. 除换行以外所有字符
[] [a-w] a-w 之间任意一个字符
\d 数字[0-9]
\D 非数字
\w 数字、字母、下划线、中文
\W 非\w 的字符
\s 所有的空白字符
\S 非空白

数量修饰

符号 含义
* 任意多次 (>= 0 次)
+ 至少一次 (>= 1 次
? 可有可无(0 或 1 次)
{m} 固定 m 次
{m, } 至少 m 次
{m, n} m-n 次

边界:

符号 含义
$ 以某某结束
^ 以某某开头

分组:

符号 含义
(){4} 视为一个整体 这个括号里面整体重复匹配4次
() 子模式\组模式,一个小括号就是一个子模式 ,可以通过 \1 来表示第一个小括号匹配的内容,\2 来表示第二个小括号# 匹配的内容。

贪婪模式:

符号 含义
.* 贪婪,一直匹配到最后一个符合的
.+? 加问号 取消贪婪。

其他的小东西

符号 含义
re.I: 忽略大小写
re.M 多行匹配
re.S 单行匹配 , 可以理解为 . 可以匹配换行符了
re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;
re.search 匹配整个字符串,直到找到一个匹配。
re.findall 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

下面我们来演示一下
一般我们用 pattern 表示正则 ,string表示需要匹配的字符

import re

string = '<p><div><span>猪八戒</span></div></p>'
pattern = re.compile(r'<(\w+)><(\w+)>\w+</\2></\1>')
ret = pattern.search(string)
print(ret)
# 结果是:<re.Match object; span=(3, 30), match='<div><span>猪八戒</span></div>'>

string = '<div>还是猪八戒</div></div>'
pattern = re.compile(r'<div>.*</div>')
pattern1 = re.compile(r'<div>.*?</div>')
ret = pattern.search(string)
ret1 = pattern1.search(string)
print(ret)
print(ret1)
#ret:<re.Match object; span=(0, 22), match='<div>还是猪八戒</div></div>'>
#ret1:<re.Match object; span=(0, 16), match='<div>还是猪八戒</div>'>
string ='''
I LOVE you
love she
LOve her
loVE me
'''

pattern = re.compile(r'^love')
ret = pattern.search(string)
print(ret)  #ret: None

pattern = re.compile(r'^love', re.M) # 多行匹配
ret = pattern.search(string)
print(ret)  #ret: <re.Match object; span=(11, 15), match='love'>

pattern = re.compile(r'^love', re.M | re.I)# 忽略大小写的多行匹配
ret = pattern.findall(string)
print(ret)  # ['love', 'LOve', 'loVE']
string1 = ''' < div > 北国风光
千里冰封
万里雪飘
望长城内外
惟余莽莽
大河上下
顿失滔滔
山舞银蛇
原驰蜡象
欲与天公试比高
</div > </div >
'''

pattern = re.compile(r'<div>(.*)</div>', re.S)
re = pattern.findall(string1)
print(re)
# [' 北国风光\n千里冰封\n万里雪飘\n望长城内外\n惟余莽莽\n大河上下\n顿失滔滔\n山舞银蛇\n原驰蜡象\n欲与天公试比高\n</div>']

pattern = re.compile(r'<div>(.*?)</div>', re.S)
re = pattern.findall(string1)
print(re)
# [' 北国风光\n千里冰封\n万里雪飘\n望长城内外\n惟余莽莽\n大河上下\n顿失滔滔\n山舞银蛇\n原驰蜡象\n欲与天公试比高\n']

pattern = re.compile(r'<div>.*?</div>', re.S)
re = pattern.findall(string1)
print(re)
# ['<div> 北国风光\n千里冰封\n万里雪飘\n望长城内外\n惟余莽莽\n大河上下\n顿失滔滔\n山舞银蛇\n原驰蜡象\n欲与天公试比高\n</div>']
# 正则替换
string = 'I love you ,you love me'

pattern = re.compile(r'love')
ret = re.sub(r'love', 'hate', string)
# r'love' 的地方也可以替换为 pattern.

# ret = pattern.sub('hate', string)
print(ret)
# re.sub 中传递函数
# 把匹配到的数字减10
string = '我士大夫撒旦123阿斯顿是发'
pattern = re.compile(r'\d+')


def fn(a):
    # print(a) a是对象
    ret = int(a.group())
    # print(ret)
    return str(ret - 10)


ret = pattern.sub(fn, string)
print(ret)

实例:爬取笑话大全的图片

就是这个 ->笑话大全

开始是想爬取 励志名言的,但是刚才试了一下,网页打不开了,我也不知道为什么,就先爬这个看看算了

先看看这个页面,就是这样,虽然我觉得也不好笑(小声

在这里插入图片描述

然后点击下一页看看有啥变化
在这里插入图片描述
现在我们有思路了,知道了,页码的规律,再检查元素看看

在这里插入图片描述

我们找到了图片的地址,现在要做的,就是解析出这个地址,然后向它发送请求,下载图片

爬虫思路:

  1. 拼接每一页的url
  2. 发送请求,解析得到图片的真实地址
  3. 向图片的地址发送请求,实现下载图片

我们用requests库来实现

import requests
import re
import os
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}
# 下面是源码,对照这个写正则表达式
# <img class="joke-main-img lazy" style="width: 720px; height: 352px;" src="https://static.hahamx.cn/images/pic_none.png" data-original="//image.hahamx.cn/2020/03/21/normal/2928575_ab639c92d1f7879b935f6f63014a03ca_1584761977.jpg"/>
def downlode_img(cn, name):
    pattern = re.compile(
        r'<img class="joke-main-img lazy".*?src=".*?" data-original="(.*?)"/>')
    ret = pattern.findall(cn)
    # print(len(ret))  # 看看找了多少个
    # 遍历列表,下载图片
    for image_src in ret:
        # 拼接一下下
        image_src = 'http:'+image_src
        # 给下载的图片起个名字
        file_name = image_src.split('_')[-1]
        # 下载的路径
        file_path = name+'\\'+file_name
        # file_path = name+'/'+file_name
        print("图片 %s 开始下载..." % file_name)
        # 下载的图片是二进制
        img = requests.get(image_src).content
        with open(file_path, 'wb') as f:
            f.write(img)
        print("图片 %s 下载完成" % file_name)
        time.sleep(0.5)

def main():
    start_page = int(input('请输入起始页码:'))
    end_page = int(input('请输入结束页码:'))
    url_old = 'https://www.hahamx.cn/pic/new/'
    for page in range(start_page, end_page + 1):
        # 新建个文件夹:
        name = 'spader\\day6\\'+str(page)
        os.mkdir(name)
        # 拼接url
        url = url_old+str(page)
        # 发送请求,获取响应
        content = requests.get(url=url, headers=headers).text
        # 解析内容,提取图片链接 下载图片
        print('第%d页开始下载...' % page)
        downlode_img(content, name)
        print('第%d页下载完成' % page)
        print()
        time.sleep(1)

        # with open('day5/sds.txt', 'wb') as f:
        #    f.write(content)
        # print(content)


if __name__ == "__main__":
    main()

注意啊:这个网站在更新,可能你写正则的时候,第一页还有10张图片,但可能写好后,图片少了,记得回去看看现在有多少图片,再看正则解析了多少,然后判断正则写的对不对。

来一个图看看爬取的结果

在这里插入图片描述



注意:爬虫在入门后,主要是爬取的思路,不然等到后面爬的东西多了,步骤复杂了容易乱,所以开始爬取之前一定要记下来思路是什么。

今天的爬虫就到这里吧,下次我们学习xpath解析方法


我又来要赞了,如果觉得可以学到点什么的话,点个赞再走吧,欢迎路过的大佬评论指正

发布了50 篇原创文章 · 获赞 50 · 访问量 2705

猜你喜欢

转载自blog.csdn.net/weixin_45691686/article/details/105022153