Python爬虫笔记(一)正则表达式提取

目录

1.认识Python网络爬虫

2.网络爬虫步骤

3.网络爬虫常见类型与应用领域

4.数据提取技术基础:正则表达式基础

5.实战:批量爬取天善智能学院课程数据

5.1 明确目标 (确定你准备爬取哪个网站的内容)

5.2 爬(下载该网页源代码到本地内存中)

5.3 取(通过正则表达式取出我们想要的数据)


1.认识Python网络爬虫

网络爬虫是一种互联网信息的自动化采集程序,主要作用是代替人工对互联网中的数据进行自动采集与整理,以快速地、批量地获取目标数据。
从技术手段来说,网络爬虫有多种实现方案,如PHP、Python(Urllib、requests、scrapy、selenium…)…但,网络爬虫的难点并不在于网络爬虫本身,而在于网页的分析与爬虫的反爬攻克问题。

 

2.网络爬虫步骤

  1. 明确目标 (确定你准备爬取哪个网站的内容)
  2. 爬 (下载该网页源代码到本地内存中,将网站的所有内容全部爬下来)
  3. 取 (通过表达式取出我们想要的数据)
  4. 处理数据(按照我们想要的方式存储和使用)

 

3.网络爬虫常见类型与应用领域

如下所示,是网络爬虫可以做的一些事情:

  1. 批量采集某个领域的招聘数据,对某个行业的招聘情况进行分析
  2. 批量采集某个行业的电商数据,以分析出具体热销商品,进行商业决策
  3. 采集目标客户数据,以进行后续营销
  4. 批量爬取腾讯动漫的漫画,以实现脱网本地集中浏览
  5. 开发一款火车票抢票程序,以实现自动抢票


4.数据提取技术基础:正则表达式基础

网络爬虫程序在将网页爬下来之后,其中还有一个关键的步骤就是需要对我们关注的目标信息进行提取,而表达式一般就是用于信息筛选提取的工具。这里简要介绍一下正则表达式的使用。

基础1:

全局匹配函数使用格式: re.compile(正则表达式).findall(源字符串)

字符含义
普通字符正常匹配
\w匹配字母、数字、下划线
\W匹配除字母、数字、下划线
\t匹配制表符
\s匹配空白字符
\S匹配除空白字符
\n匹配换行符
\d匹配十进制数字
\D匹配除十进制数字
[ab89x]原子表,匹配ab89x中的任意一个
[^ab89x]原子表,匹配除ab89x以外的任意一个字符

实例1:

源字符串:"aliyunedu"

正则表达式:"yu"

匹配结果: yu

 

源字符串:'''aliyun

edu'''

正则表达式:"yun\n"

匹配结果: yun\n

 

源字符串:"aliyu89787nedu"

正则表达式:"\w\d\w\d\d\w"

匹配结果: u89787

 

源字符串:"aliyu89787nedu"

正则表达式:"\w\d[nedu]\w"

匹配结果: 87ne

 

基础2:

字符含义
+前一个字符出现1\多次
|模式选择符或
{n}前一个字符恰好出现n次
{n,m}前一个字符至少n,至多m次
{n,}前一个字符至少n次
^匹配开始位置
?前一个字符出现0\1次
.匹配除换行外任意一个字符
*前一个字符出现0\1\多次
()模式单元,通俗来说就是:想提取出什么内容,就在正则中用小括号将其括起来
$匹配结束位置

实例2:

源字符串:'''aliyunnnnji87362387aoyubaidu'''

 

正则表达式:"ali..."

匹配结果: aliyun

 

正则表达式:"^li..."

匹配结果: None

 

正则表达式:"^ali..."

匹配结果: aliyun

 

正则表达式:"bai..$"

匹配结果: baidu

 

正则表达式:"ali.*"

匹配结果: aliyunnnnji87362387aoyubaidu

Tips:默认贪婪,即默认尽可能多地进行匹配

 

正则表达式:"aliyun+"

匹配结果: aliyunnnn

 

正则表达式:"aliyun?"

匹配结果: aliyun

 

正则表达式:"yun{1,2}"

匹配结果: yunn

 

正则表达式:"^al(i..)."

匹配结果: iyu

 

基础3:

贪婪模式:尽可能多地匹配

懒惰模式:尽可能少地匹配,精准模式

 

默认贪婪模式

如果出现如下组合,则代表为懒惰模式:

*?

+?

 

实例3:

源字符串:"poytphonyhjskjsa"

正则表达式:"p.*y"

匹配结果:? poytphony

为什么? 默认贪婪模式

 

源字符串:"poytphonyhjskjsa"

正则表达式:"p.*?y"

匹配结果: ['poy', 'phony']

为什么? 懒惰模式,精准匹配

 

基础4:

模式修正符:在不改变正则表达式的情况下通过模式修正符使匹配结果发生更改

re.S 让 . 也可以匹配多行

re.I  匹配时忽略大小写

 

实例4:

源字符串:"Python"

正则表达式:"pyt"

匹配方式:re.compile("pyt").findall("Python")

匹配结果: []

 

源字符串:"Python"

正则表达式:"pyt"

匹配方式:re.compile("pyt",re.I).findall("Python")

匹配结果: Pyt

 

源字符串:string="Python"

正则表达式:"pyt"

匹配方式:re.compile("pyt",re.I).findall("Python")

匹配结果: Pyt

 

源字符串:string="""我是阿里云大学

欢迎来学习

Python网络爬虫课程

"""

正则表达式:pat="阿里.*?Python"

匹配方式:re.compile(pat).findall(string)

匹配结果: []

 

源字符串:string="""我是阿里云大学

欢迎来学习

Python网络爬虫课程

"""

正则表达式:pat="阿里.*?Python"

匹配方式:re.compile(pat,re.S).findall(string)

匹配结果: ['阿里云大学\n欢迎来学习\nPython']

 

5.实战:批量爬取天善智能学院课程数据

使用上面的知识编写一个简单的网络爬虫:爬取天善智能学院课程数据

 

5.1 明确目标 (确定你准备爬取哪个网站的内容)

目标网址:https://edu.hellobi.com/
目标数据:取出该网站所有课程的 课程名、课程讲师、课程价格,也就是下图红框中的内容。

 

5.2 爬(下载该网页源代码到本地内存中)

通过如下代码我们就可以将该网页的源代码全部爬取下来,保存到本地内存中:

#导入包urllib.request
import urllib.request

#设定要爬取的网站url
thisurl="https://edu.hellobi.com/course/308"

#使用函数urlopen访问该网站,使用函数read将访问网站的源代码全部下载到内存中,使用函数decode设定UTF-8中文编码,并忽略一些错误
data=urllib.request.urlopen(thisurl).read().decode("utf-8","ignore")

到这一步我们已经将下图中的网页源代码下载到了本地内存中,在网页 右键->查看网页中的源代码,即可看到爬取的内容。

 

5.3 取(通过正则表达式取出我们想要的数据)

首先需要分析网页,选中要取出的内容,在源代码中ctrl+f搜索要取出的内容,即可看到该内容在网页源代码中的位置,如下:

取具有唯一性的代码段进行正则匹配,使用如下代码,取出这门课的课程名:

#导入包urllib.request
import urllib.request

#设定要爬取的网站url
thisurl="https://edu.hellobi.com/course/308"

#使用urlopen函数访问该网站,使用read函数将访问网站的源代码全部下载到内存中,使用decode函数设定UTF-8中文编码,并忽略一些错误
data=urllib.request.urlopen(thisurl).read().decode("utf-8","ignore")
    
#根据源代码编写匹配的正则表达式,(.*?)就是我们要取出的部分
title_pat='<li class="active">(.*?)</li>'

#使用re包中的compile函数编译正则匹配表达式,re.S代表可以换行匹配,使用findall函数选定数据集,也就是爬取的所有源代码
title=re.compile(title_pat,re.S).findall(data)

#打印出课程名
print(title)

运行结果如下: 

价格和老师的提取办法依此类推如下:

价格的源代码:

老师所在的源代码: 

使用如下代码,取出这门课的课程名、价格、老师:

import urllib.request
import re

thisurl="https://edu.hellobi.com/course/308"
data=urllib.request.urlopen(thisurl).read().decode("utf-8","ignore")

title_pat='<li class="active">(.*?)</li>'
title=re.compile(title_pat,re.S).findall(data)
print(title)

price_pat='div class="course-price">.*?<sub>¥</sub>(.*?)<b></b></span>'
price=re.compile(price_pat,re.S).findall(data)
print(price)

teacher_pat='class="lec-name">(.*?)<'
teacher=re.compile(teacher_pat,re.S).findall(data)
print(teacher)

运行结果如下:

我们的目标是要取出所有课程的名字,价格以及老师,可以发现每个课程的网址url只有最后的数字不同,所以这里可以使用for循环取出所有课程的数据。

 

最终代码如下:

import urllib.request
import re
for i in range(0,1000):
    thisurl="https://edu.hellobi.com/course/"+str(i+1)
    data=urllib.request.urlopen(thisurl).read().decode("utf-8","ignore")

    title_pat='<li class="active"(.*?)</li>'
    teacher_pat='class="lec-name">(.*?)<'
    price_pat='div class="course-price">.*?<sub>¥</sub>(.*?)<b></b></span>'

    title=re.compile(title_pat,re.S).findall(data)
    if(len(title)>0):
        title=title[0]
    else:
        continue

    teacher=re.compile(teacher_pat,re.S).findall(data)
    if(len(teacher)>0):
        teacher=teacher[0]
    else:
        teacher="缺失"

    price=re.compile(price_pat,re.S).findall(data)
    if(len(price)>0):
        price=price[0]
    else:
        price="免费"

    print(title)
    print(price)
    print(teacher)
    
    print("--------------")

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风影楼前

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值