学习笔记-爬虫-正则表达式与文件操作

内容是对《Python爬虫开发:从入门到实战》的摘录、理解、代码实践和遇到的问题。

在爬虫的开发中,需要把有用的信息从一大串文本中提取出来。正则表达式是提取信息的方法之一,虽然不是最简单也不是最高效的方法,但是最直接的,而且在某些情况下只有正则表达式才能达到目的。

该部分主要知识:

  1. 正则表达式的基本符号
  2. 如何在python中使用正则表达式
  3. 正则表达式的提取技巧
  4. Python读写文本文件和CSV文件

正则表达式Regular Expression

正则表达式是一段字符串,可以表示一段有规律的信息。Python自带一个正则表达式的模块,通过这个模块可以查找、提取、替换一段有规律的信息。

使用正则表达式的步骤:

  1. 寻找规律
  2. 使用正则符号表示规律
  3. 提取信息

正则表达式基本符号

点号“.”

一个点号可以代替除了换行符以外的任何一个字符。

星号“*”

一个星号可以表示它前面的一个子表达式(普通字符、另一个或几个正则表达式符号)0次到无限次。

问号“?”

问号表示它前面的子表达式出现0次或1次。注意是英文问号。

反斜杠“\”

转义符,和其他字符配合使用,把特殊符号变成普通符号或把普通符号变成特殊符号。

数字“\d”

正则表达式里面使用“\d”来表示一位数字。

小括号“()”

小括号可以把括号里面的内容提取出来。

在Python中使用正则表达式

Python的正则表达式模块名字为“re”(也即regular expression的首字母缩写),需要先导入再使用,导入语句为:

import re

findall

以列表的形式返回所有满足要求的字符串

       findall的函数原型: re.findall(pattern, string, flags=0)

       其中pattern表示正则表达式,string表示需要提取的字符串,flags表示一些特殊功能的标志(flags参数可以省略,当不省略时具有一些辅助功能,如忽略大小写、忽略换行符等)。

       findall的结果是一个列表,包含了所有匹配到的结果,如果没有匹配到结果就会返回一个空列表。

import re



content = '密码1是:123, 密码2是:345, 密码3是:564,密码4未定'

password_list = re.findall(':(.*?),', content)

cantFindAnythingSample = re.findall('名字是:(.*?),', content)

print(password_list)

print(cantFindAnythingSample)

['123', '345', '564']

[]

在一个正则表达式中使用多个()

正则表达式是用来表示出需要的数据的格式,例如上面例子,我们所需要提取的密码串总是以”:”开头,以”,”结尾,所以正则表达式是‘:(.*?),‘,但提取结果中我们并不需要:和, 所以并没有把它们放入括号内。即:我们可以使用小括号()来选取需要返回的部分

如果一个正则表达式中包含多个小括号,findall()返回的仍是一个列表,但列表内的元素变为元组,正则表达式里有几个小括号,元组里就有几个元素,以下面同时匹配账号和密码为例:

import re



content = '网站1的账号是:123,密码是:234,网站2的账号是:kae,密码是:345a,网站3的账号是:ryrt,密码是:234,'

account_password = re.findall('账号是:(.*?),密码是:(.*?),', content)

print(account_password)

[('123', '234'), ('kae', '345a'), ('ryrt', '234')]

注意中英文标点符号

       注意:使用正则表达式的过程中,中英文标点符号混淆常常会导致各种问题,特别是冒号、逗号和引号,在中英文输入法中看上去非常相似但对于计算机而言是不一样的,需要格外注意。

re.findfall() flags参数使用示例,以忽略换行符为例

可以在flags参数 的位置填入re.S以此实现忽略换行符

import re



content = '''

密码是:123

456,

'''



withoutFlags = re.findall('密码是:(.*?),', content)

withFlags = re.findall('密码是:(.*?),', content, re.S)

print(withoutFlags)

print(withFlags)

[]

['123\n456']

       可见当存在待提取数据中存在换行符时,可能导致整个数据都提取不到,使用re.S可以防止这种情况,虽然提取的结果中多出了‘\n‘但可以在后期数据清洗时洗掉。

search

search()的用法和findall()一样,不同的是search()只会返回第一个满足要求的字符串,一旦找到符合要求的内容就会停止查找。在文本很大且只需要第一个数据时能大幅提高效率。

search()的函数原型是 re.search(pattern, string, flags=0)

如果没有匹配到任何数据,则返回None,如果匹配成功,则返回一个正则表达式对象,要通过.group()方法来获取里面的值,只有.group()里的参数用于指定返回正则表达式中第几个括号里的值(从1开始)

import re



content = '网站1的账号是:dasd,密码是:123,网站2的账号是:fdgs,密码是:234,网站3...'

cantGetAnythingSample = re.search('用户名是:(.*?),', content)

getFirst = re.search('账号是:(.*?),密码是:(.*?),', content)



invalid1 = getFirst  # search()得到的结果需要使用.group()方法获取括号里的值

invalid2 = getFirst.group(0)    # .group()里的参数从1开始,0是无效的

valid1 = getFirst.group(1)      # 有效写法,返回第正则表达式第一个括号匹配到的东西,即账号

valid2 = getFirst.group(2)      # 有效写法,返回第正则表达式第二个括号匹配到的东西,即密码



print(cantGetAnythingSample)

print(invalid1)

print(invalid2)

print(valid1)

print(valid2)

None

<re.Match object; span=(4, 21), match='账号是:dasd,密码是:123,'>

账号是:dasd,密码是:123,

dasd

123

“.*”和“.*?”的区别

“.*”:贪婪模式,获取最长的满足条件的字符串

“.*?”:非贪婪模式,获取最短的满足条件的字符串

import re



content = '网站1的账号是:123,密码是:234,网站2的账号是:kae,密码是:345a,网站3的账号是:ryrt,密码是:234,'

withQueMark = re.findall('账号是:(.*?),', content)

withoutQueMark = re.findall('账号是:(.*),', content)

print(withQueMark)

print(withoutQueMark)

['123', 'kae', 'ryrt']

['123,密码是:234,网站2的账号是:kae,密码是:345a,网站3的账号是:ryrt,密码是:234']

Python文件操作

Python的文件操作涉及对文件的读/写与编码的处理,是学习爬虫的必备知识。

使用Python读写文本文件

open

open用于打开一个文件并创建一个文件对象。有两种写法。

1、需要手动关闭文件

f = open('文件路径', '文件操作方式', encoding='utf-8')

对文件进行操作

f.close()

2、使用Python的上下文管理器,不需要手动关闭文件,只要代码退出了缩进,Python就会自动关闭文件。

with open('文件路径', '文件操作方式', encoding='utf-8') as f:

       对文件进行操作

因为程序开发中经常会出现忘记关闭文件的情况,所以推荐使用第二种写法。

open()参数

‘文件路径‘     可以是绝对路径,也可以是相对路径。其中相对路径是相对于现在的工作区而言的,并不总是相对于正在运行的这个Python文件的路径(?)。在本章中先直接将文本文件和Python文件放在一起,这样可以直接使用文件名打开文本文件。

‘文件操作方式‘     在读文件的时候,这个参数可以省略,也可以写成‘r’。在写文件的时候写成’w’或‘a’,使用’w’新内容会覆盖原文件,而用’a’则会把新内容写到原文件的末尾。

‘encoding’     可以指定文件的编码格式,从而避免出现乱码。(如果文件是在Windows中创建的,并且使用UTF-8打开文件出现了乱码,可以把编码格式改为GBK)

读文本文件

文件内容:

with open('text.txt', encoding='utf-8') as f:

    res1 = f.readlines()   # 读取所有行并以列表的形式返回

print(res1)

['第一行\n', '第二行\n', '第三行']

写文本文件

with open('text.txt', 'w', encoding='utf-8') as f:

    f.write("直接将一整个字符串写入文本文件中用write()方法")

with open('text.txt', 'w', encoding='utf-8') as f:

    # 把一个列表里所有的内容写入文本文件中用writelines()方法

    f.writelines(['第一段话', '第二段话', '第三段话'])

 

 

需要注意不管是哪种方法都是不会自动换行的,如果需要换行需要人工输入换行符,方法如下:

f.write('\n')

使用Python读写CSV文件

CSV文件本质上就是文本文件,但如果直接用文本编辑器打开可读性并不高。用Excel或Numbers打开,则能得到可读性很高的表格。

Python自带操作CSV的模块csv,使用这个模块可以将CSV文件的内容转换为Python的字典。

读CSV文件

由于CSV文件本质上是一个文本文件,所以需要先以文本文件的方式打开,再将文件对象传递给csv模块

CSV文件内容:

 

import csv



with open('file.csv', encoding='utf-8') as f:

    reader = csv.DictReader(f)

    for row in reader:

        print(row)

OrderedDict([('\ufeffuserName', 'uer1'), ('age', '14')])

OrderedDict([('\ufeffuserName', 'uer2'), ('age', '21')])

【Python问题解决】利用Python读取文件时出现\ufeff的原因及解决办法_python ufeff_奋斗中的编程菜鸟的博客-CSDN博客

原因分析

utf-8编码的文件时开头会有一个多余的字符\ufeff,在读文件时会读到\ufeff

解决办法

只需改一下编码就行,把 UTF-8 编码 改成 UTF-8-sig编码即可

其中得到的row是OrderedDict(有序字典),可以直接像普通字典那样使用

with open('file.csv', encoding='UTF-8-sig') as f:

    reader = csv.DictReader(f)

    for row in reader:

        userName = row['userName']

        age = row['age']

        print('用户名:{}, 年龄:{}'.format(userName, age))

用户名:uer1, 年龄:14

用户名:uer2, 年龄:21

写CSV文件

Python可以把一个字典或者一个包含字典的列表写成CSV文件。

写CSV文件时需要指定列名,列名要和字典的Key一一对应。

csv.DictWriter(文件对象f,fieldnames = 字典的Key列表)

import csv



data = [

    {'name': 'uer1', 'age': 24, 'sex': 'male'},

    {'name': 'uer9', 'age': 22, 'sex': 'male'},

    {'name': 'uer12', 'age': 20, 'sex': 'female'}

]



with open('file.csv', 'w', encoding='UTF-8-sig') as f:

    writer = csv.DictWriter(f, fieldnames=['name', 'age', 'sex'])   # 只到一行为止文件里什么都没有

    writer.writeheader()    # 写入列行名

    writer.writerows(data)  # 写入数据

    writer.writerow({'name': 'uer14', 'age': 26, 'sex': 'female'})  

最后一行演示了可以用.writerow(字典)写入单个字典,不需要关心Key的顺序,但字典里不能存在fieldnames里面没有的Key,也不能缺少fieldnames里已有的Key。

 

Python 写入 csv 文件中空行解决办法_李正旺的Python空间的博客-CSDN博客

改为

with open('file.csv', 'w', encoding='UTF-8-sig', newline="") as f:

后,空行问题解决。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值