教你数据解析神功,成为PC端爬虫工程师的高手!

数据解析是爬虫工程师采集数据的重要环节,它的目的是从爬取到的网页中提取出需要的数据。常用的数据解析方法有正则表达式、XPath、BeautifulSoup等。

其中,正则表达式是一种强大的文本匹配工具,可以用来匹配和提取文本中的特定模式。在爬虫中,正则表达式通常用于匹配HTML标签中的内容,例如匹配网页中的标题、链接、图片等。

正则表达式的基本语法包括字符集、量词、分组、反向引用等。例如,要匹配一个HTML标签中的链接,可以使用以下正则表达式:


其中,\s+表示匹配一个或多个空格,[“']表示匹配单引号或双引号,[^”']+表示匹配除了单引号和双引号以外的任意字符,.*?表示匹配任意字符,但是尽可能少地匹配。

在使用正则表达式进行数据解析时,需要注意以下几点:

  • 正则表达式的语法较为复杂,需要仔细学习和理解。
  • 正则表达式的性能较差,对于大规模数据解析可能会影响爬虫的效率。
  • 正则表达式只能匹配文本,对于非文本数据(如图片、视频等)无法处理。

因此,在实际爬虫开发中,需要根据具体情况选择合适的数据解析方法。

关注公众号:python技术训练营,精选优质文档,好玩的项目

教你数据解析神功,成为PC端爬虫工程师的高手!_第1张图片

内容

1.面试专题几十个大厂面试题
2.入门基础教程
3.11模块零基础到精通笔记
4.百个项目实战+爬虫教程+代码
5.量化交易,机器学习,深度学习
6.Python游戏源码
7.交流学习
8.了解接单市场
9.DNF自动识别打怪
10.3263页学习资料

一丶正则表达式

1.正则原理概述

在爬虫中,数据解析是非常重要的一环,因为数据解析模块的好坏将直接决定了爬虫的效率和准确度。正则表达式是数据解析中常用的一种技术,下面就来简要介绍一下正则表达式的原理。

正则表达式(Regular Expression)即为正则或称规则表达式,是一套用于描述、匹配和处理文本的符号规则。在爬虫中,正则表达式常被用于从HTML文本中提取出我们需要的数据。正则表达式的语法非常强大,包括字符集、元字符、量词、分组等许多特性,能够满足各种复杂的匹配需求。下面简要介绍一些正则表达式的语法:

字符集

字符集(Character Classes,也称字符组)一般用方括号表示,用于表示一组可选字符。比如,[abc]表示可选任意一个字母a、b或c。其中还有一些常用的简写形式,如\d表示任意一个数字(等价于[0-9]),\w表示任意一个字母、数字或下划线(等价于[a-zA-Z0-9_]),\s表示任意一个空白字符(包括空格、制表符、回车符等)。

元字符

元字符(Metacharacters)是正则表达式中具有特殊含义的字符,如 \、^、$、*、+、?、.、|、()、{m,n} 等等。这些字符在正则表达式中并非表示字面意义,而是具有某种特殊的含义。

量词

量词用于指定字符或子表达式出现的次数,常用的量词包括:

  • *:表示任意个字符(包括零个字符)
  • +:表示至少一个字符
  • ?:表示零个或一个字符
  • {m}:表示恰好出现 m 次
  • {m,n}:表示至少出现 m 次,最多出现 n 次

分组

分组用小括号括起来,用于将多个部分组合在一起。分组还允许应用量词,即在一个组内表示一定数量的字符。

当然,正则表达式也存在一些限制。由于正则表达式本身较为复杂,容易出现逻辑上的错误,在使用时需要注意。此外,在处理海量数据时,正则表达式的效率可能会成为影响程序性能的瓶颈。

综上所述,正则表达式是数据解析中非常常用的一种技术,掌握正则表达式的语法规则,能够更方便地从HTML文本中提取出所需的数据。

2.分组和通用匹配

正则表达式是一种用于匹配文本的工具,它可以用来解析HTML、XML等文本格式的数据。在正则表达式中,分组和通用匹配是两个常用的概念。

1.分组

分组是指将正则表达式中的一部分用括号括起来,形成一个子表达式。分组可以用来限定匹配范围、提取匹配结果等。

例如,正则表达式(.?)中,用括号括起来的部分就是分组,第一个分组(.?)用来匹配链接地址,第二个分组(.*?)用来匹配链接文本。

2.通用匹配

通用匹配是指用.来匹配任意字符的正则表达式。通用匹配可以用来匹配一些不确定的字符,例如空格、换行符等。

例如,正则表达式.*?中,用.来匹配链接地址和链接文本中间的任意字符,这样就可以匹配包含任意字符的链接了。

需要注意的是,通用匹配可能会匹配到一些不需要的字符,因此在使用时需要谨慎。

3.贪婪和非贪婪模式**

在爬虫工程师的采集工作中,数据解析是非常重要的一环节。正则表达式是一种强大的工具,可以用于从网页中提取有用的信息。在正则表达式中,贪婪和非贪婪模式是一个关键的概念,因为它们直接影响到正则表达式的匹配结果。

正则表达式中的贪婪模式指的是匹配尽可能多的字符,而非贪婪模式则是匹配尽可能少的字符。默认情况下,正则表达式是贪婪的,这意味着它会尝试匹配尽可能多的字符。例如,考虑以下正则表达式:

.*hello.*

该正则表达式将匹配任何字符串,只要它包含子字符串“hello”。但是,如果我们使用该正则表达式对以下字符串进行匹配:

"hello world! hello goup!"

结果将是整个字符串,而不仅仅是第一个“hello”字符串。这是因为正则表达式会贪婪地匹配尽可能多的字符,直到找到最后一个“hello”。

要使用非贪婪模式,可以在正则表达式中使用“?”符号。例如,如果我们想要上面的正则表达式只匹配第一个“hello”,可以这样写:

.*?hello.*

这个正则表达式将会匹配到第一个“hello”,因为它使用了非贪婪模式,尽可能少地匹配字符,直到找到第一个“hello”。

总的来说,在数据解析和爬虫采集过程中,要根据需要选择合适的正则表达式模式。如果需要匹配尽可能多的字符,则应该使用贪婪模式;如果需要匹配尽可能少的字符,则应该使用非贪婪模式。很多时候,贪婪模式会导致意外的匹配结果,因此需要特别小心。

4.findall/match/search方法

在Python中,re模块提供了三种方法来匹配正则表达式:findall、match和search。

findall方法

findall方法可以在字符串中查找所有匹配正则表达式的子串,并返回一个列表。例如:

import re

text = 'Hello, my name is John. My email is [email protected].'
emails = re.findall(r'\b\w+@\w+\.\w+\b', text)
print(emails)

输出结果为:

['[email protected]']

match方法

match方法只能在字符串的开头匹配正则表达式,如果匹配成功,则返回一个匹配对象,否则返回None。例如:

import re

text = 'Hello, my name is John. My email is [email protected].'
match = re.match(r'\b\w+@\w+\.\w+\b', text)
if match:
    print(match.group())
else:
    print('No match')

输出结果为:

No match

因为正则表达式\b\w+@\w+.\w+\b只能匹配单词边界处的邮箱地址,而字符串的开头不是单词边界。

search方法

search方法可以在字符串中查找第一个匹配正则表达式的子串,并返回一个匹配对象,否则返回None。例如:

import re

text = 'Hello, my name is John. My email is [email protected].'
match = re.search(r'\b\w+@\w+\.\w+\b', text)
if match:
    print(match.group())
else:
    print('No match')

输出结果为:

[email protected]

因为search方法会在整个字符串中查找匹配正则表达式的子串。

二丶xpath

XPath是一种用于在XML文档中定位元素和属性的语言,也可以用于HTML文档的解析。在PC端爬虫工程师采集数据时,XPath可以帮助我们快速准确地定位到需要的数据。

XPath的语法比较简单,主要由路径表达式和基本表达式组成。路径表达式用于定位元素,基本表达式用于定位属性或文本。

以下是一些常用的XPath表达式:

定位元素

  • //tagname:选取所有名称为tagname的元素

  • /tagname:选取根元素下的所有名称为tagname的元素

  • /path/tagname:选取路径为path下的所有名称为tagname的元素

定位属性

  • //@attribute:选取所有名称为attribute的属性

  • /path/@attribute:选取路径为path下的所有名称为attribute的属性

定位文本

  • //tagname/text():选取所有名称为tagname的元素的文本内容

  • /path/tagname/text():选取路径为path下的所有名称为tagname的元素的文本内容

XPath的使用需要借助解析库,比如Python中的lxml库。使用lxml库可以通过xpath()方法来解析HTML或XML文档,获取需要的数据。

例如,以下代码可以获取百度首页的搜索框的名称:

import requests
from lxml import etree

url = 'https://www.baidu.com/'
response = requests.get(url)
html = etree.HTML(response.text)
input_name = html.xpath('//input[@id="kw"]/@name')[0]
print(input_name)

输出结果为:

'wd'

这里使用了xpath表达式//input[@id="kw"]/@name来定位搜索框元素的名称属性。

1.dom节点

在使用XPath进行数据解析时,需要了解DOM节点的概念。

DOM(Document Object Model)是一种用于表示和操作HTML或XML文档的标准对象模型。在DOM中,文档被表示为一个树形结构,每个节点都是一个对象,包含了文档中的元素、属性、文本等信息。

在XPath中,每个节点都有一个节点类型,常见的节点类型包括:

  • 元素节点(Element Node):表示XML或HTML文档中的元素,如

    等。

  • 属性节点(Attribute Node):表示XML或HTML文档中的属性,如class、id等。
  • 文本节点(Text Node):表示XML或HTML文档中的文本内容,如
    hello world
    中的hello world。

在XPath中,可以使用不同的语法来选择DOM节点,常见的语法包括:

  • 路径表达式(Path Expression):使用路径表达式可以选择文档中的某个节点或一组节点。例如,选择所有的
    元素可以使用路径表达式//div。
  • 轴(Axis):轴是一种用于选择节点的方法,可以选择与当前节点有特定关系的节点。例如,选择当前节点的所有子节点可以使用轴child::。
  • 谓语(Predicate):谓语是一种用于过滤节点的方法,可以根据节点的属性或位置等信息来选择节点。例如,选择第一个
    元素可以使用路径表达式(//div)[1]。

掌握DOM节点的概念和XPath的语法,可以更加灵活地进行数据解析。

2.xpath语法学习

XPath(XML Path Language)是一种用于在XML文档中定位元素和属性的语言。XPath使用路径表达式来选择和操作XML文档中的节点。

以下是XPath语法中的一些基本概念:

  • 节点:XML文档中的元素、属性等都是节点。
  • 路径表达式:一种用来表示选择某个节点或一组节点的字符串。
  • 路径:路径指定从文档根节点到所选节点的方式,可以是绝对路径或相对路径。
  • 谓语:谓语用于筛选节点,可以是一个表达式或条件。

XPath语法示例:

选择节点

//book  //表示从任意节点开始检索
/book  /表示从根节点开始检索
book   表示选择名为"book"的节点

选择属性

//@class  选择所有名为"class"的属性

谓语

//student[age>20]  选择名为"student"且"age"大于20的节点
层级://bookstore/book/title 选择所有名为"bookstore"的节点下的名为"book"的节点下的名为"title"的节点

XPath的语法非常直观,容易理解和记忆。在使用XPath语法进行数据解析时,可以使用Python中的lxml库来实现,使用方法也非常简单。使用lxml库和XPath语法,可以将HTML或XML文档中的数据提取出来并保存为结构化数据,用于后续的分析和处理。

3.xpath定位文章数据

在使用XPath定位文章数据时,需要先用浏览器开发者工具分析文章页面的HTML结构,找出要提取的数据所在的节点,然后使用XPath语法来筛选这些节点。

以下是一个示例,假设我们要从一个博客的文章页面中提取文章标题、作者、发布时间和正文:


  
    Blog Title
  
  
    

Article Title

Author Name

2023-06-09 20:08:20

Article Content Paragraph 1

Article Content Paragraph 2

Article Content Paragraph 3

使用XPath语法,可以定位到需要提取的节点:

//h1[@class='title']  # 定位到文章标题节点
//p[@class='author']  # 定位到作者节点
//p[@class='publish-time']  # 定位到发布时间节点
//div[@class='content']/p  # 定位到正文每一段的节点

然后使用Python中的lxml库解析HTML,提取出这些节点的文本内容:

from lxml import etree

# 解析HTML
html = etree.parse('article.html', etree.HTMLParser())

# 提取节点文本
title = html.xpath('//h1[@class="title"]/text()')[0]
author = html.xpath('//p[@class="author"]/text()')[0]
publish_time = html.xpath('//p[@class="publish-time"]/text()')[0]
content = '\n'.join(html.xpath('//div[@class="content"]/p/text()'))

这样就可以将文章的信息提取出来,其中titleauthorpublish_time为字符串,content为字符串列表,每个元素为正文中的一段。后面可以根据需要将这些数据保存到文件或数据库中,或者进行其他的数据处理。

三丶Beautiful

在进行网页数据解析时,我们需要使用一些工具来帮助我们快速地定位和提取所需的数据。其中,Beautiful Soup是一个非常常用的Python库,它可以帮助我们解析HTML和XML文档,并提供了一些方便的方法来定位和提取数据。

安装Beautiful Soup

在使用Beautiful Soup之前,我们需要先安装它。可以使用pip命令来安装:

pip install beautifulsoup4

使用Beautiful Soup

安装完成后,我们就可以开始使用Beautiful Soup了。下面是一个简单的例子,演示了如何使用Beautiful Soup来解析HTML文档:

from bs4 import BeautifulSoup

html_doc = """


    这是一个示例页面


    

欢迎来到我的网站

这是一个示例页面,用于演示Beautiful Soup的使用方法。

""" soup = BeautifulSoup(html_doc, 'html.parser') print(soup.prettify())

在这个例子中,我们首先定义了一个HTML文档的字符串,然后使用Beautiful Soup的构造函数来创建一个BeautifulSoup对象。构造函数的第二个参数指定了解析器的类型,这里我们使用了Python内置的html.parser解析器。

接下来,我们调用了BeautifulSoup对象的prettify()方法,将解析后的HTML文档格式化输出。这个方法可以将HTML文档按照标准的缩进格式输出,方便我们查看和调试。

定位元素

在使用Beautiful Soup解析HTML文档时,我们通常需要定位文档中的某些元素,然后提取它们的内容或属性。Beautiful Soup提供了一些方便的方法来定位元素,下面是一些常用的方法:

  • find()方法:查找文档中第一个符合条件的元素。
  • find_all()方法:查找文档中所有符合条件的元素,并返回一个列表。
  • select()方法:使用CSS选择器语法查找文档中符合条件的元素。

下面是一个例子,演示了如何使用这些方法来定位元素:

from bs4 import BeautifulSoup

html_doc = """


    这是一个示例页面


    

欢迎来到我的网站

这是一个示例页面,用于演示Beautiful Soup的使用方法。

""" soup = BeautifulSoup(html_doc, 'html.parser') # 使用find()方法查找第一个符合条件的元素 title = soup.find('title') print(title) # 使用find_all()方法查找所有符合条件的元素 links = soup.find_all('a') for link in links: print(link) # 使用select()方法使用CSS选择器语法查找元素 content = soup.select('.content') print(content)

在这个例子中,我们首先使用find()方法查找了文档中的第一个title元素,并将其打印出来。接下来,我们使用find_all()方法查找了所有的a元素,并使用for循环将它们打印出来。最后,我们使用select()方法使用CSS选择器语法查找了所有class为content的元素,并将其打印出来。

提取内容和属性

在定位到元素后,我们通常需要提取它们的内容或属性。Beautiful Soup提供了一些方便的方法来实现这个功能,下面是一些常用的方法:

  • text属性:获取元素的文本内容。
  • string属性:获取元素的文本内容,与text属性类似,但是对于一些特殊的标签(如script、style等)会返回None。
  • get()方法:获取元素的指定属性值。

下面是一个例子,演示了如何使用这些方法来提取内容和属性:

from bs4 import BeautifulSoup

html_doc = """


    这是一个示例页面


    

欢迎来到我的网站

这是一个示例页面,用于演示Beautiful Soup的使用方法。

""" soup = BeautifulSoup(html_doc, 'html.parser') # 获取元素的文本内容 title_text = soup.title.text print(title_text) # 获取元素的指定属性值 link = soup.find('a') link_href = link.get('href') print(link_href)

在这个例子中,我们首先使用text属性获取了title元素的文本内容,并将其打印出来。接下来,我们使用find()方法查找了第一个a元素,并使用get()方法获取了它的href属性值,并将其打印出来。

总结

Beautiful Soup是一个非常常用的Python库,它可以帮助我们解析HTML和XML文档,并提供了一些方便的方法来定位和提取数据。在使用Beautiful Soup时,我们通常需要使用find()find_all()select()等方法来定位元素,然后使用text、stringget()等方法来提取内容和属性。

2.基于bs4的环境搭建

在使用BeautifulSoup之前,需要先安装bs4库。可以使用pip命令安装:

pip install bs4

环境搭建完成后,可以进行以下操作。

初始化BeautifulSoup对象

BeautifulSoup初始化时需要两个参数,第一个参数是HTML或XML文档的字符串,第二个参数是指定使用哪种解析器进行解析。常用的解析器包括html.parserlxmlhtml5lib,其中lxml解析器解析速度较快,而html5lib解析器则能够处理一些语法非常松散的HTML文档。

以下是根据HTML文档初始化BeautifulSoup对象的代码:

from bs4 import BeautifulSoup

html_doc = '''

    网页标题


    

网页正文

第一段内容

第二段内容

第三段内容

''' soup = BeautifulSoup(html_doc, 'html.parser') # 使用html.parser解析器初始化BeautifulSoup对象

查找元素

使用BeautifulSoup中的find()find_all()方法可以查找符合条件的元素。find()方法返回第一个符合条件的元素,find_all()方法返回符合条件的所有元素。

以下是根据标签和属性查找元素的代码:

# 查找所有p元素
ps = soup.find_all('p')
for p in ps:
    print(p.get_text())

# 查找所有class属性值为content的元素
contents = soup.find_all(class_='content')
for content in contents:
    print(content.get_text())

提取元素属性

使用元素对象的attrs属性可以获取所有属性值,使用get()方法可以获取某个特定属性值。

以下是根据属性提取元素的代码:

# 获取所有a标签的href属性
a_s = soup.find_all('a')
for a in a_s:
    print(a['href'])

# 获取第一个a标签的href属性
a = soup.find('a')
print(a.get('href'))

使用CSS选择器

使用BeautifulSoupselect()方法可以通过CSS选择器查找元素。

以下是使用CSS选择器的代码:

# 查找所有class属性值为content的div元素下的所有p元素
ps = soup.select('.content p')
for p in ps:
    print(p.get_text())

# 查找第一个ul元素下的所有li元素
lis = soup.select('ul li')
for li in lis:
    print(li.get_text())

BeautifulSoup提供了许多方法可以方便地操作HTML和XML文档,具体使用可以参照官方文档进行。

3.bs4节点选择器

在使用BeautifulSoup解析HTML代码时,通过节点选择器可以选择HTML文档中的指定部分,常用的节点选择器包括标签选择器、类选择器、id选择器、属性选择器等。

标签选择器

标签选择器是最常用的选择器,它根据HTML标签名称来选择HTML文档中的元素。可以使用find()或find_all()方法来实现标签选择器。

# 选择第一个p标签
soup.find('p')

# 选择所有p标签
soup.find_all('p')

类选择器

类选择器是通过元素的class属性进行选择,可以使用CSS选择器语法来选择单个或多个类。

# 选择class为"foo"的元素
soup.select('.foo')

# 选择同时具有class为"foo"和"bar"的元素
soup.select('.foo.bar')

id选择器

id选择器是根据id属性进行选择,可以使用CSS选择器语法选择具有指定id的元素。可以使用find()方法来实现id选择器。

# 选择id为"myid"的元素
soup.find(id='myid')

属性选择器

属性选择器是根据元素的属性值来选择元素。可以使用find_all()方法和属性名选择单个或多个元素。

# 选择所有具有href属性的a标签
soup.find_all('a', href=True)

子选择器

子选择器是通过选择器名称的空格分隔符来实现选择父元素下的子元素。

# 选择div元素下的所有p元素
soup.select('div p')

后代选择器

后代选择器使用选择器名称的大于号>分隔符来实现选择某个父元素下的直接子元素。

# 选择div元素下的直接子元素p元素
soup.select('div > p')

兄弟选择器

兄弟选择器是指选择与指定元素处于同一层级但不一定是相邻的元素。可以使用选择器名称的+符号选择下一个兄弟元素,使用选择器名称的~符号选择所有兄弟元素。

# 选择id为"foo"元素的下一个兄弟元素
soup.select('#foo + p')

# 选择id为"foo"元素的所有兄弟元素
soup.select('#foo ~ p')

以上就是使用BeautifulSoup的节点选择器的常用方法,基于选择器的使用,可以解析和提取HTML文档中的各种元素和属性信息。

4.bs4属性选择器

在Beautiful Soup中,我们可以使用属性选择器来选择具有特定属性的标签。属性选择器使用方括号[]来指定属性名称和属性值。

以下是一些常用的属性选择器:

选择具有特定属性的标签

soup.select('tag[attr]')

例如,选择所有具有class属性的div标签:

soup.select('div[class]')

选择具有特定属性和属性值的标签

soup.select('tag[attr=value]')

例如,选择所有class属性为"example"的div标签:

soup.select('div[class=example]')

选择具有特定属性但不限制属性值的标签

soup.select('tag[attr*]')

例如,选择所有具有id属性的标签:

soup.select('[id*]')

选择具有特定属性值的标签,但不限制属性名称

soup.select('[*=value]')

例如,选择所有属性值包含"example"的标签:

soup.select('[*=example]')

选择具有多个属性的标签

soup.select('tag[attr1][attr2]')

例如,选择所有同时具有class属性为"example"和id属性为"test"的div标签:

soup.select('div[class=example][id=test]')

5.bs4层级选择器

BeautifulSoup库提供了一些层级选择器,可以用于选择HTML文档中的指定层级元素。层级选择器可以嵌套使用,以实现更精细的元素选择。

以下是bs4层级选择器的几个常见方法:

descendants选择器

该选择器用于选择当前元素的所有后代元素,包括子元素、子元素的子元素、子元素的子元素的子元素等。使用descendants方法进行查找,返回所有后代元素的生成器对象。

# 选择id为"content"的div元素的所有后代元素
for elem in soup.find('div', id='content').descendants:
    print(elem)

children选择器

该选择器用于选择当前元素的所有子元素,不包括子元素的子元素。使用children方法进行查找,返回当前元素的所有子元素的生成器对象。

# 选择id为"content"的div元素的所有子元素
for elem in soup.find('div', id='content').children:
    print(elem)

parent选择器

该选择器用于选择当前元素的父元素,使用parent方法进行查找,返回当前元素的父元素。

# 选择id为"myid"的元素的父元素
parent = soup.find(id='myid').parent

parents选择器

该选择器用于选择当前元素的所有祖先元素,返回一个生成器对象。与descendants方法不同,该方法只返回直接祖先元素,不包括更远的祖先元素。

# 选择id为"myid"的元素的所有祖先元素
for ancestor in soup.find(id='myid').parents:
    print(ancestor)

next_siblingprevious_sibling选择器

next_sibling选择器用于选择当前元素的下一个兄弟元素,previous_sibling选择器用于选择当前元素的上一个兄弟元素。

# 选择id为"myid"的元素的下一个兄弟元素
next_sibling = soup.find(id='myid').next_sibling

以上就是bs4层级选择器的常见方法,这些方法可以很好地帮助我们选择HTML文档中的特定元素来进行后续的数据提取和处理。

关注公众号:python技术训练营,精选优质文档,好玩的项目

教你数据解析神功,成为PC端爬虫工程师的高手!_第2张图片

内容

1.面试专题几十个大厂面试题
2.入门基础教程
3.11模块零基础到精通笔记
4.百个项目实战+爬虫教程+代码
5.量化交易,机器学习,深度学习
6.Python游戏源码
7.交流学习
8.了解接单市场
9.DNF自动识别打怪
10.3263页学习资料

你可能感兴趣的:(python开发,python,python爬虫,爬虫,python,职场和发展,学习,数据分析)