【Python爬虫】Python爬虫开发:从入门到实战(谢乾坤)[1-3]

在这里插入图片描述

第2章 Python 基础

2.3 Python的数据结构和控制结构

元组和列表的区别:

列表生成以后还可以往里面继续添加数据,也可以从里面删除数据;但是元组一旦生成就不能修改。如果它里面只有整数、浮点数、字符串、另一个元组,就既不能添加数据,也不能删除数据,还不能修改里面数据的值。但是如果元组里面包含了一个列表,那么这个元组里面的列表依旧可以变化。

切片操作

格式为:

变量名[开始位置下标:结束位置下标:步长]

切片的结果包括“开始位置下标”所对应的元素,但是不包括“结束位置下标”所对应的元素。

列表末尾添加元素

Append,例如:

   >>> list_4 = ['Python', ’爬虫’]>>> print(list_4)['Python', ’爬虫’]>>> list_4.append(’一’)>>> print(list_4)['Python', ’爬虫’, ’一’]>>> list_4.append(’酷’)>>> print(list_4)['Python', ’爬虫’, ’一’, ’酷’]

元组和字符串不能添加新的内容,不能修改元组里面的非可变容器元素,也不能修改字符串里面的某一个字符。

通过Key来从字典中读取对应的Value,

有3种主要的格式:

    变量名[key]
    变量名.get(key)
    变量名.get(key, ’在找不到key的情况下使用这个值’)

例如:

    >>> example_dict = {'superman': ’超人是一个可以在天上飞的两足兽’, ’天才’: ’天才跑在时代的前面,把时代拖得气喘吁吁。','xx': 0, 42: '42是一切的答案’}>>> print(example_dict[’天才’])
    天才跑在时代的前面,把时代拖得气喘吁吁。
    >>> print(example_dict.get(42))42是一切的答案
    >>> print(example_dict.get(’不存在的key'))None>>> print(example_dict.get(’不存在的key', ’找不到’))
    找不到

使用方括号的方式来读取字典的Value时,一定要保证字典里面有这个Key和它对应的Value,否则程序会报错。
使用get来读取,如果get只有一个参数,那么在找不到Key的情况下会得到“None”;如果get有两个参数,那么在找不到Key的情况下,会返回第2个参数。

修改已存在字典的Key对应Value/增加新的Key-Value对

变量名[key] = ’新的值’

如果Key不存在,就会创建新的Key-Value对;如果Key已经存在,就会修改它的原来的Value。例如:

  >>> existed_dict = {'a': 123, 'b': 456}>>> print(existed_dict){'b': 456, 'a': 123}>>> existed_dict['b'] = ’我修改了b'
    >>> print(existed_dict){'b': ’我修改了b', 'a': 123}>>> existed_dict['new'] = ’我来也’
    >>> print(existed_dict){'b': ’我修改了b', 'a': 123, 'new': ’我来也’}

需要特别注意的是,字典的Key的顺序是乱的,所以不能认为先添加到字典里面的数据就排在前面。

集合去重

集合最大的应用之一就是去重。
例如,把一个带有重复元素的列表先转换为集合,再转换回列表,那么重复元素就只会保留一个。 把列表转换为集合需要使用set()函数,把集合转换为列表使用list()函数:

duplicated_list = [3, 1, 3, 2, 4, 6, 6, 7, 's', 's', 'a']
unique_list = list(set(duplicated_list))
print(unique_list)
[1, 2, 3, 4, 's', 6, 7, 'a']

由于集合与字典一样,里面的值没有顺序,因此使用集合来去重是有代价的,代价就是原来列表的顺序也会被改变。

使用字典实现多重条件控制

如果有多个if,写起来会很烦琐,例如下面这一段代码:

  if state == 'start':
      code = 1elif state == 'running':
      code = 2elif state == 'offline':
      code = 3elif state == 'unknown':
      code = 4else:
      code = 5

使用“if…elif…else…”会让代码显得冗长。如果使用字典改写,代码就会变得非常简洁:

    state_dict = {'start': 1,'running': 2, 'offline': 3, 'unknown': 4}
    code = state_dict.get(state, 5)

for循环

for 循环从列表中取出每个元素

name_list=['a','b','c','d']
for name in name_list:
    print(name)

for循环从每个字符串里面获得一个字符

title="大家好,我叫EasyLake"
for character in title:
    print (character)

这里的每一个汉字、每一个字母、每一个标点符号都会被for循环分开读取。循环第1次得到的是“大”,第2次得到的是“家”,第3次得到的是“好”,以此类推。
在做爬虫的时候会遇到需要把列表展开的情况,常犯的一个错误就是把字符串错当成了列表展开。这个时候就会得到不正常的结果。

for循环把字典展开得到里面每一个key

menu_dict = {'红烧肉':'100元','水煮肉片':'50元','鸡汤':'1角'}
for key in menu_dict:
    print('菜品:{}'.format(key))
    print('价格:{}'.format(menu_dict[key]))
    print("---------------")

通过指定range里面的数字,可以控制循环的执行次数。需要特别注意的是,i是从0开始的。

在某些特殊的情况下,确实需要循环永远运行,这个时候需要这样写:

    import time
    while True:
      你要执行的代码
      time.sleep(1)

如果要让循环永久运行,那么增加一个延迟时间是非常有必要的。time.sleep()的参数为一个数字,单位为秒。如果不增加这个延迟时间,就会导致循环超高速运行。在爬虫的开发过程中,如果超高速运行,很有可能导致爬虫被网站封锁。

第3章正则化表达式与文件操作

3.1 .1正则表达式的基本符号

1. 点号“.”:一个点号可以代替除了换行符以外的任何一个字符

一个点号可以代替除了换行符以外的任何一个字符,包括但不限于英文字母、数字、汉字、英文标点符号和中文标点符号。例如,有如下几个不同的字符串:

kingname
kinabcme
kin123me
kin我是谁me
kin嗨你好me
kin"m"me`                

这些字符串的前3个字符都是“kin”,后两个字符都是“me”,只有中间的3个字符不同。如果使用点号来表示,那么全部都可以变成kin…me的形式,中间有多少个字就用多少个点。

2.星号“*”

只有一个星号 *:它前面的子表达式0次到无限次

一个星号表示它前面的一个子表达式(普通字符、另一个或几个正则表达式符号)0次到无限次。
例如,有如下几个不同的字符串:

 如果快乐你就笑哈
    如果快乐你就笑哈哈
    如果快乐你就笑哈哈哈哈
    如果快乐你就笑哈哈哈哈哈哈哈哈哈

这些字符串里面,“哈”字重复出现,所以如果用星号来表示,那么就可以全部变成:

如果快乐你就笑哈*
如果快乐你就笑*

由于星号可以表示它前面的字符0次,所以即使写成“如果快乐你就笑”,没有“哈”字,也是满足这个正则表达式的。

一个点号+一个星号 .*

既然星号可以表示它前面的字符,那么如果它前面的字符是一个点号呢?例如下面这个正则表达式:

    如.*

它表示在“如”和“哈”中间出现“任意多个除了换行符以外的任意字符”。这句话看起来有点绕,用下面几个字符串来说明,它们全部都可以用上面的这个正则表达式来表示:

    如哈
    如果快乐哈
    如果快乐你就笑哈
    如果你知道1+1=2那么请计算地球的半径哈
    如aklsdjfjaf哈

3.问号“? ”

问号表示它前面的子表达式0次或者1次。注意,这里的问号是英文问号。
例如下面这两个不同的字符串:

 笑起来。
 笑起来哈。

在汉字“来”和中文句号之间有0个或者1个“哈”字,都可以使用下面这个正则表达式来表示:

    笑起来哈?。
点号+星号+问号 .*?

问号最大的用处是与点号和星号配合起来使用,构成“.*? ”。通过正则表达式来提取信息的时候,用到最多的也是这个组合。
下面的所有字符串:

    如哈
    如果快乐哈
    如果快乐你就笑哈
    如果你知道1+1=2那么请计算地球的半径哈
    如aklsdjfjaf哈

都可以用下面这个正则表达式来表示:
如.*?哈`

.* 和.* ?d 的区别:
前者为贪婪模式,获取最长的满足条件的字符串;后者为非贪婪模式,获取最短的能满足条件的字符串。
前者最多只能匹配一个,后者可以匹配多个。

4.反斜杠/

反斜杠不仅可以把特殊符号变成普通符号,还可以把普通符号变成特殊符号。例如“n”只是一个普通的字母,但是“\n”代表换行符。
在这里插入图片描述

5.数字“\d”:表示一位数字

正则表达式里面使用“\d”来表示一位数字。为什么要用字母d呢?因为d是英文“digital(数字)”的首字母。
再次强调一下,“\d”虽然是由反斜杠和字母d构成的,但是要把“\d”看成一个正则表达式符号整体。
如果要提取两个数字,可以使用\d\d;如果要提取3个数字,可以使用\d\d\d。但是如果不知道这个数有多少位怎么办呢?就需要用*号来表示一个任意位数的数字。
下面一段字符串:

123455677,请记住它。
    是1,请记住它。
    是66666,请记住它。

全部都可以使用下面这个正则表达式来表示:

\d*:一个任意位数的数字。

6.小括号“()”:把括号里面的内容提取出来。

前面讲到的符号仅仅能让正则表达式“表示”一串字符串。但是如果要从一段字符串中“提取”出一部分的内容应该怎么办呢?这个时候就需要使用小括号了。
有如下一个字符串:
我的密码是:12345abcde你帮我记住。
可以看出,这里的密码左边有一个英文冒号,右边有一个汉字“你”。当构造一个正则表达式:.*?你时,得到的结果将会是:
:12345abcde你
然而,冒号和汉字“你”并不是密码的一部分,如果只想要“12345abcde”,就需要使用括号:
:(.*? )你
得到的结果就是:
12345abcde

3.1.2在Python中使用正则表达式

Python的正则表达式模块名字为“re”,也就是“regular expression”的首字母缩写。在Python中需要首先导入这个模块再进行使用。导入的语句为:
import re

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

Python的正则表达式模块包含一个findall方法,它能够以列表的形式返回所有满足要求的字符串。
findall的函数原型为:
re.findall(pattern, string, flags=0)
pattern表示正则表达式,string表示原来的字符串,flags表示一些特殊功能的标志。
findall的结果是一个列表,包含了所有的匹配到的结果。如果没有匹配到结果,就会返回空列表。
当需要提取某些内容的时候,使用小括号将这些内容括起来,这样才不会得到不相干的信息。如果包含多个“(.? )”怎么返回呢?如图3-2所示,返回的仍然是一个列表,但是列表里面的元素变为了元组,元组里面的第1个元素是账号,第2个元素为密码。

图3-2 多个括号内的内容会以元组形式返回
请注意代码中的冒号和逗号,图3-1代码中为中文冒号和中文逗号;图3-2代码中为英文冒号和英文逗号。在实际使用正则表达式的过程中,中英文标点符号混淆常常会导致各种问题。特别是冒号、逗号和引号,虽然中英文看起来非常相似,但实际上中文冒号和英文冒号是不一样的,中文逗号和英文逗号也是不一样的。在某些字体里面,这种差异甚至无法察觉,因此在涉及正则表达式中的标点符号时,最好直接复制粘贴,而不要手动输入。
函数原型中有一个flags参数。这个参数是可以省略的。当不省略的时候,具有一些辅助功能,例如忽略大小写、忽略换行符等。这里以忽略换行符为例来进行说明,如图3-3所示。

图3-3 使用re.S作为flag来忽略换行符
在爬虫的开发过程中非常容易出现这样的情况,要匹配的内容存在换行符“\n”。要忽略换行符,就需要使用到“re.S”这个flag。虽然说匹配到的结果中出现了“\n”这个符号,不过总比什么都得不到强。内容里面的换行符在后期清洗数据的时候把它替换掉即可。

V3-6 search的使用
2.search
search()的用法和findall()的用法一样,但是search()只会返回第1个满足要求的字符串。一旦找到符合要求的内容,它就会停止查找。对于从超级大的文本里面只找第1个数据特别有用,可以大大提高程序的运行效率。
search()的函数原型为:

re.search(pattern, string, flags=0)
对于结果,如果匹配成功,则是一个正则表达式的对象;如果没有匹配到任何数据,就是None。如果需要得到匹配到的结果,则需要通过.group()这个方法来获取里面的值,如图3-4所示。

图3-4 使用.group()来获取search()方法找到的结果
只有在.group()里面的参数为1的时候,才会把正则表达式里面的括号中的结果打印出来。
group()的参数最大不能超过正则表达式里面括号的个数。参数为1表示读取第1个括号中的内容,参数为2表示读取第2个括号中的内容,以此类推,如图3-5所示。

图3-5 .group()的参数意义

V3-7 (.
)和(.? )的区别
3.“.
”和“.? ”的区别
在爬虫开发中,.
?这3个符号大多数情况下一起使用。
点号表示任意非换行符的字符,星号表示匹配它前面的字符0次或者任意多次。所以“.”表示匹配一串任意长度的字符串任意次。这个时候必须在“.”的前后加其他的符号来限定范围,否则得到的结果就是原来的整个字符串。
如果在“.”的后面加一个问号,变成“.? ”,那么可以得到什么样的结果呢?问号表示匹配它前面的符号0次或者1次。于是.?的意思就是匹配一个能满足要求的最短字符串。
这样说起来还是非常抽象,下面通过一个实际的例子来进行说明。请看下面这一段话:

我的微博密码是:1234567, QQ密码是:33445566, 银行卡密码是:888888, Github密码是:999abc999,帮我记住它们
这段话有一个显著的规律,即密码是:xxxxxx, ”,也就是在“密码是”这3个汉字的后面跟一个中文的冒号,冒号后面是密码,密码后面是中文的逗号。
如果想把这4个密码提取出来,可以构造以下两个正则表达式:

密码是:(.
),
密码是:(.? ),
配合Python的findall方法,得到结果如图3-6图所示。

图3-6 使用“.*”和“.*? ”返回的结果
使用“(.
)”得到的是只有一个元素的列表,里面是一个很长的字符串。
使用第2个正则表达式“(.? )”,得到的结果是包含4个元素的列表,每个元素直接对应原来文本中的每个密码。
举一个例子,10个人肩并肩并排站着,使用“(.
)”取到了第1个人左手到第10个人右手之间的所有东西,而使用“(.? )”取到的是“每个人”的左手和右手之间的东西。
一句话总结如下。
①“.
”:贪婪模式,获取最长的满足条件的字符串。
②“.? ”:非贪婪模式,获取最短的能满足条件的字符串。
3.1.3 正则表达式提取技巧
1.不需要compile
网上很多人的文章中,正则表达式使用re.compile()这个方法,导致代码变成下面这样:

import re
example_text = ’我是kingname, 我的微博账号是:kingname, 密码是:12345678, QQ账号是:99999, 密
码是:890abcd, 银行卡账号是:000001, 密码是:654321, Github账号是:99999@qq.com, 密码
是:7777love8888, 请记住他们。'
new_pattern=re.compile(’账号是:(.
? ), 密码是:(.*? ), ', re.S)
user_pass = re.findall(new_pattern, example_text)
print(user_pass)

V3-8 正则表达式提取技巧
这种写法虽然结果正确,但纯粹是画蛇添足,是对Python的正则表达式模块没有理解透彻的体现,是从其他啰嗦的编程语言中带来的坏习惯。如果阅读Python的正则表达式模块的源代码,就可以看出re.compile()是完全没有必要的。
对比re.compile()和re.findall()在源代码中的写法,如图3-7所示的两个方框。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解锁网络数据的宝藏:Python爬虫工具与教程集合 一、探索网络信息的无限宝藏 在互联网的海洋中,蕴藏着海量的有价值信息。如何合法、高效地获取这些信息?Python爬虫工具与教程为您揭开这一神秘面纱。通过这些资源,您可以轻松地爬取网站信息,提取所需内容,为各种应用场景提供强大的数据支持。 二、资源亮点 工具齐全:提供一系列功能强大的Python爬虫工具,满足您不同场景下的需求。 教程详尽:配套的Python爬虫教程,从基础到进阶,让您逐步掌握爬虫的核心技术。 合法合规:严格遵守法律法规和网站使用协议,确保采集行为合法,尊重网站权益。 实战项目:结合实际案例,让您在实践中掌握Python爬虫的运用,真正做到学以致用。 三、适用人群 无论您是数据分析师、网络开发者还是对Python爬虫感兴趣的爱好者,这些资源都将为您的学习和实践提供有力的支持。 四、使用建议 按需选择工具与教程:根据实际需求选择合适的工具和教程,确保学习与实践的有效性。 遵守法律法规与协议:在使用这些资源进行爬取活动时,务必遵守相关法律法规和网站的使用协议。 持续学习与更新:随着网络技术的不断进步,Python爬虫技术也在不断发展。建议您持续关注相关动态,提升自己的技能水平。 五、安全与责任 尊重网站权益:避免对目标网站的正常运行造成干扰或损害,合理使用资源。 隐私保护:在采集数据时,严格遵守隐私保护法规,不泄露或滥用用户个人信息。 风险防范:了解并应对潜在的网络威胁,采取相应措施降低风险。 感您选择我们的Python爬虫工具与教程集合!让我们一起挖掘网络信息的宝藏,为您的工作和研究注入新的活力!请务必遵守法律法规和网站使用协议,共同维护网络数据的合法采集与利用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值