python爬虫二—网络数据解析

一、正则表达式

1.为什么要学正则表达式

爬虫一共四个主要步骤:

  1. 明确目标 (要知道你准备在哪个范围或者网站去搜索)
  2. 爬 (将所有的网站的内容全部爬下来)
  3. 取 (去掉对我们没用处的数据)
  4. 处理数据(按照我们想要的方式存储和使用)

2.什么是正则表达式

正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述小例子:
在这里插入图片描述

在这里插入图片描述
3.re 模块一般使用步骤

  1. 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
    注意: re对特殊字符进行转义,如果使用原始字符串,只需加一个 r 前缀
  2. 通过 Pattern 对象对文本进行匹配查找,获得匹配结果,一个 Match 对象。
  3. 使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作

在这里插入图片描述
正则表达式实现步骤

import re

text = """
2020-10-10
2020-11-11
2030/12/12
"""

# 1. 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
# 注意: re对特殊字符进行转义,如果使用原始字符串,只需加一个 r 前缀
pattern = re.compile(r'\d{4}-\d{1,2}-\d{1,2}')    # 2020-4-11, 无分组的规则
pattern = re.compile(r'(\d{4})-(\d{1,2})-(\d{1,2})')    # 2020-4-11, 有分组的规则
pattern = re.compile(r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})')  # 2020-4-11, 有命名分组的规则
#  2. 通过 Pattern 对象对文本进行匹配查找,获得匹配结果,一个 Match 对象。
# search从给定的字符串中寻找一个符合规则的字符串, 只返回一个
result = re.search(pattern, text)
print(result)
# 3. 使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作
print("匹配到的信息:", result.group())  # 返回的是匹配到的文本信息
print("匹配到的信息:", result.groups())  # 返回的是位置分组, ('2020', '10', '10')
print("匹配到的信息:", result.groupdict())  # 返回的是关键字分组.{'year': '2020', 'month': '10', 'day': '10'}


#运行结果:
<re.Match object; span=(1, 11), match='2020-10-10'>
匹配到的信息: 2020-10-10
匹配到的信息: ('2020', '10', '10')
匹配到的信息: {'year': '2020', 'month': '10', 'day': '10'}

Pattern和Match对象方法汇总
1.pattern对象方法
正则表达式编译成 Pattern 对象, 可以利用 pattern 的一系列方法对文本进行匹配查找

Pattern 对象的一些常用方法主要有:
在这里插入图片描述2.match对象方法
match 方法用于查找字符串的头部(也可以指定起始位置),它是一次匹配,只要找到了一个匹配的结果就返回, 而不是查找所有匹配的结果。它的一般使用形式如下:match(string[, pos[, endpos]])
string :待匹配的字符串
pos :字符串的起始位置, 默认值是 0
endpos :字符串的终点位置, 默认值是 len (字符串长度)
在这里插入图片描述3.search
search 方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有 匹配的结果,它的一般使用形式如下:search(string[, pos[, endpos]])
当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None。
4.findall和finditer方法
findall 方法搜索整个字符串,获得所有匹配的结果。使用形式如下:findall(string[, pos[, endpos]])
finditer 方法的行为跟 findall 的行为类似,也是搜索整个字符串,获得所有匹配的结果。但它返回一个顺序访问每 一个匹配结果(Match 对象)的迭代器。

5.split方法
split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
maxsplit 指定最大分割次数,不指定将全部分割split(string[, maxsplit])

import re
p = re.compile(r'[\s\,\;]+')
print p.split('a,b;; c  d')

6.sub方法
sub 方法用于替换。它的使用形式如下:

sub(repl, string[, count])

repl 可以是字符串也可以是一个函数:

  • 1). 如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl 还 可以使用 id 的形式来引用分组,但不能使用编号 0;
  • 2). 如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符 串中不能再引用分组)。
    count 用于指定最多替换次数,不指定时全部替换。
import re
p = re.compile(r'(\w+) (\w+)')
s = 'hello 123, hello 456'

print(p.sub(r'hello word', s)) # 使用'hello word' 替换'hello 123, hello 456'
print(p.sub(r'\2 \1', s)) #  \数字:引用分组

def func(m):
    return 'hi' + ' ' + m.group(2)

print(p.sub(func, s))
print(p.sub(func, s, 1)) # 最多替换1次

运行结果:
在这里插入图片描述
7.匹配中文
在某些情况下,我们想匹配文本中的汉字,有一点需要注意的是,中文的 unicode 编码范围主要在 [u4e00- u9fa5],这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的。
8.正则常量
re.ASCII
re.IGNORECASE 忽略大小写
re.M 多行
re.S .代表任意字符

import re

# 1. re.ASCII
text = '正则表达式re模块'
# 匹配所有字母数字下划线, 默认匹配中文,不匹配中文时,指定flags=re.A
result = re.findall(pattern=r'\w+', string = text, flags=re.A)  # 只匹配ascii
print(result)

# 2. 忽略大小写  re.IGNORECASE
text= 'hello word HEllo python'
result = re.findall(r'he\w+o' , text, re.I)
print(result)   # ['hello', 'HEllo']

# 3. re.M 多行
text = 'hello 123 \n 234 453word '
result = re.findall(r'^he.*?', text, re.M)
print(result)

# 4. re.S  .代表任意字符
text = 'hello \n word'
result = re.findall(r'^he.*?ld$', text, re.S)
print(result)

运行结果:
在这里插入图片描述
9.贪婪模式与非贪婪模式

  • 贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配 ( * );
    使用贪婪的数量词的正则表达式 ab* ,匹配结果: abbb。
    *决定了尽可能多匹配 b,所以a后面所有的 b 都出现了。
  • 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配 ( ? );
    使用非贪婪的数量词的正则表达式 ab*? ,匹配结果: a。
    即使前面有 * ,但是 ? 决定了尽可能少匹配 b,所以没有 b。
  • Python里数量词默认是贪婪的。

项目:基于requests和正则猫眼电影top100定向爬虫

在这里插入图片描述在这里插入图片描述
本项目反爬策略
在头部加上Host和Cookie信息
cookie 位置:右击 审查元素–>网络–>Headers

headers = {
            'User-Agent': ua.random,
            'Host': 'maoyan.com',
            'Cookie': '__mta=244103482.1586583849431.1586591578863.1586591596622.7; uuid_n_v=v1; uuid=70A8E5507BB711EA904101D407E7401D56771E011B5248CCB28F41E623827FA2; _csrf=911258e83ffafda305001ded783784bef80e9113d1d47c8f8b4940dc934b9acd; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1586583838; mojo-uuid=1bf14bca5d2a510f6e85c2857cc8d257; _lxsdk_cuid=17167c43f33c8-07022459d688ce-4313f6a-144000-17167c43f33c8; _lxsdk=70A8E5507BB711EA904101D407E7401D56771E011B5248CCB28F41E623827FA2; mojo-session-id={"id":"83a8b6a56c45ba34bd30bd7e6d5c46b9","time":1586591446957}; __mta=244103482.1586583849431.1586583890672.1586591526586.6; mojo-trace-id=6; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1586591597; _lxsdk_s=171683837b1-2a5-86f-f4e%7C%7C10'}

        }

基于requests和正则猫眼电影top100定向爬虫code

使用多线程和多进程

def no_use_thread():
    for page in range(1,11):
        get_one_page(page)
        print(Fore.GREEN+'[+]采集第%s页数据' %(page))
        #反爬虫策略:速度太快被限速,在数据采集的过程中休眠几秒
        time.sleep(1)

def use_multi_thread():
    # 使用多线程实现
    from threading import Thread
    for page in range(1, 11):
        # 开启多线程,每一页
        thread = Thread(target=get_one_page, args=(page,))  # args是元组
        thread.start()
        print(Fore.GREEN + '[+]采集第%s页数据' % (page))

def use_thread_pool():
    # 使用线程池实现
    from concurrent.futures import ThreadPoolExecutor
    # 实例化线程池 并指定线程池的线程个数
    pool = ThreadPoolExecutor(100)
    pool.map(get_one_page, range(1, 11))
    print("采集结束")


if __name__ == '__main__':
    use_multi_thread()

二、XPath数据解析库

lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。
XPath (XML Path Language) 是一门在 xml文档中查找信息的语言,可用来在 xml /html文档中对元素和属性进行遍历。

  • XPath如何实现文档解析?
    1、etree库把HTML文档中的字符串解析为Element对象
    from lxml import etree
    html=etree.HTML(text)
    result=etree.tostring(html)
    2、etree库把HTML文档解析为Element对象
    html=etree.parse(‘xxx.html’)
    result=etree.tostring(html,pretty_print=True)

常用规则:
在这里插入图片描述在这里插入图片描述

2.xpath用法
在这里插入图片描述

from lxml import etree

text = """
<h1>标题一</h1>
<h2>标题二
"""

# 1. etree 把html文档中的字符串解析为Element对象
html = etree.HTML(text)
print(html) #<Element html at 0x17f7c47c808>
print(etree.tostring(html)) #b'<html><body><h1>&#26631;&#39064;&#19968;</h1>\n<h2>&#26631;&#39064;&#20108;\n</h2></body></html>'

# 2.
html = etree.parse('hello.html')
result = etree.tostring(html, pretty_print=True)
print(result)

项目:基于requests和XPath猫眼电影TOP100定向爬虫

页面分析

在这里插入图片描述

在这里插入图片描述基于requests和XPath猫眼电影TOP100定向爬虫code
运行结果:
在这里插入图片描述

项目: 基于requests和XPath的TIOBE编程语言排行榜定向爬虫

基于requests和XPath的TIOBE编程语言排行榜定向爬虫code

页面分析:在这里插入图片描述在这里插入图片描述运行结果:生成tiobe.csv文件

在这里插入图片描述

这里涉及到CSV文件的读写操作:
在这里插入图片描述

import csv

# # 1. 通过reader方式读取文件内容,每行内容是一个列表
# with open('hello.csv') as f:
#     csv_reader = csv.reader(f)
#     for row in csv_reader:
#         print(row)    # 返回的是列表

#2. 通过Dictreader方式读取文件,每行是字典
# with open('hello.csv') as f:
#     csv_reader = csv.DictReader(f)
#     for row in csv_reader:
#         print(row)    # OrderedDict([('name', 'zhangsan'), ('age', '10')])
#         print('名称:',row['name'])
#         print('年龄:',row['age'])

# # 3. 通过writer写入文件,必须传入一个列表
# info = [
#     ('zhangsan',10),
#     ('lisi',20),
# ]
# with open('writer.csv','w',encoding='utf-8') as f:
#     csv_writer = csv.writer(f)
#     # 一次写入多行内容
#     csv_writer.writerows(info)
#     # for循环, 一次写入一行内容
#     for row in info:
#         csv_writer.writerow(row)

# 4. 通过DictWriter方式写入文件,必须传入一个字典
with open('writer.csv','w',encoding='utf-8') as f:
    # 传两个值:文件名称,字典KEY值(表头)
    csv_writer = csv.DictWriter(f,['name','password'])  # 表头
    for row in range(10):
        csv_writer.writerow({
            'name':'name'+str(row),
            'password':'password'+str(row)
        })

    # for row in data:
    #     csv_writer.writerow(row)

三、BeautifulSoup数据解析库

Beautiful Soup 4.4.0是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.
BS4基本用法

# 1. 从bs4模块中导入BeautifulSoup
from bs4 import BeautifulSoup
html = """
<h1> bs4 </h1>
"""
# 2.实例化BeautifulSoup对象,并通过指定的解析器(4种)解析html字符串的内容
soup = BeautifulSoup(html,'lxml') # 使用'lxml'解析器
result = soup.prettify()
print(result)

运行结果:
在这里插入图片描述

BS4的节点选择器代码
在这里插入图片描述
BS4的方法选择器代码
在这里插入图片描述
BS4的CSS选择器代码

项目:基于requests和BS4的三国演义名著定向爬虫

思路分析:
在这里插入图片描述
页面分析:
章节的页面:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述基于requests和BS4的三国演义名著定向爬虫代码
运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值