爬虫学习----解析网页

解析网页就是从服务器请求下来的网页数据中提取出我们需要的数据,常用的有三种方法:正则表达式解析网页、BeautifulSoup和lxml。

一、使用正则表达式解析网页

正则表达式就是对字符串操作的一种逻辑公式,就是用事先定义好的特定字符和这些特定字符的组合组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑。因此,当我们获得网页数据后,就需要先将数据转换为字符串,之后再用正则表达式去匹配我们需要的内容。正则表达式的规则如下:

模式描述模式描述
.匹配任意字符,除了换行符\s匹配空白字符
*匹配前一个字符0次或多次\S匹配任意非空白字符
+匹配前一个字符1次或多次\d匹配数字,等价于[0-9]
匹配前一个字符0次或1次\D匹配任何非数字,等价于[^0-9]
^匹配字符串开头\w匹配字母数字,等价于[A-Za-z0-9]
$匹配字符串末尾\W匹配非字母数字,等价于[^A-Za-z0-9]
()匹配括号内的表达式,也表示一个组[]用来表示一组字符

接下来,Python有三种正则表达式的匹配方法:re.match、re.search和re.findall

1. re.match方法

匹配规则是从字符串的起始位置开始匹配,只匹配一个,如果匹配不到就返回none。

# re.match方法
import re
m = re.match("www", "www.baidu.com")
print("匹配的结果:", m)
print("匹配的起始和终点位置:", m.span())
print("匹配的起始位置:", m.start())
print("匹配的终点位置:", m.end())
匹配的结果: <_sre.SRE_Match object; span=(0, 3), match='www'>
匹配的起始和终点位置: (0, 3)
匹配的起始位置: 0
匹配的终点位置: 3
# 使用正则表达式匹配
line = "Fat cats are smarter than dogs, is it right?"
m = re.match(r'(.*) are (.*?) dogs', line)
print("匹配的整句话:", m.group(0))
print("匹配的第一个结果:", m.group(1))
print("匹配的第二个结果:", m.group(2))
print("匹配的结果列表:", m.groups())
匹配的整句话: Fat cats are smarter than dogs
匹配的第一个结果: Fat cats
匹配的第二个结果: smarter than
匹配的结果列表: ('Fat cats', 'smarter than')

在匹配的正则表达式中,有(.*)和(.*?)两个表达式,?表示非贪婪模式,意思是尽可能少的匹配。

2. re.search方法

匹配规则是扫描整个字符串,并返回第一个成功匹配的字符串

m_match = re.match('com', 'www.bad,com')
m_search = re.search('com', 'www.abd.com,www.baidu.com')
print(m_match)
print(m_search)
None
<_sre.SRE_Match object; span=(8, 11), match='com'>

3. re.findall方法

匹配规则是找到所有符合正则表达式的字符串。

m_findall = re.findall('[0-9]+', '123 is 123,456 is 456')
print(m_findall)
['123', '123', '456', '456']

二、使用BeautifulSoup解析网页

BeautifulSoup可以从HTML或XML文件中提取数据,它是一个工具箱,通过解析文档为用户提供需要抓取的数据。

使用BeautifulSoup获取博客标题

import requests
from bs4 import BeautifulSoup

link = "http://www.santostang.com/"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
r = requests.get(link, headers=headers)

# 转化响应内容为soup对象
soup = BeautifulSoup(r.text, "html.parser")
# 找到代码中class为post-title的h1标签
title_list = soup.find_all("h1", class_="post-title")
for i in range(len(title_list)):
    # 提取元素a中的文字,并去掉空格
    title = title_list[i].a.text.strip()
    print("第%s篇文章的标题是:%s" % (i+1, title))
第1篇文章的标题是:4.3 通过selenium 模拟浏览器抓取
第2篇文章的标题是:4.2 解析真实地址抓取
第3篇文章的标题是:第四章- 动态网页抓取 (解析真实地址 + selenium)
第4篇文章的标题是:《网络爬虫:从入门到实践》一书勘误
第5篇文章的标题是:Hello world!

BeautifulSoup对象是一个复杂的树形结构,每一个节点都是一个Python对象。获取网页内容就是一个提取对象内容的过程。有三种提取对象的方法,分别为:遍历文档树、搜索文档树和CSS选择器。

1. 遍历文档树

文档树的遍历方法就是要一级级的去查找,比如想要获取<h3>标签。

soup.header.h3

搜索某个标签的所有子节点,可以用contents把所有子节点以列表的方式输出

soup.header.div.contents

还可以索引列表的不同索引,获得不同的内容

soup.header.div.contents[1]

children获取子标签,descendants获得子子孙孙的节点,parent方法获得父节点的内容。

for child in soup.header.div.children:
    print(child)

for child in soup.header.div.descendants:
    print(child)

a_tag = soup.header.div.a
a_tag.parent

2. 搜索文档树

使用find()和fand_all()方法进行搜索文档树。

title_list = soup.find_all("h1", class_="post-title")

3. CSS选择器

CSS选择器方法既可以作为遍历文档树的方法提取数据,也可以作为搜索文档树的方法提取数据。,可以通过tag标签逐层查找。

soup.select("header h3")
soup.select("header > h3")

这两种得到的结果是相同的。

也可以实现搜索文档树的功能,如选择以链接www.baidu.com开始的,<a>标签。

soup.select('a[href^="http://www.baidu.com/"]')

三、使用lxml解析网页

使用lxml提取网页源代码也有三种方法:XPath选择器、CSS选择器和BeautifulSoup的find()方法。使用XPath选择器来获取数据。

import requests
from lxml import etree
link = "http://www.santostang.com/"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
r = requests.get(link, headers=headers)

# 解析为lxml格式
html = etree.HTML(r.text)
# 使用xpath读取内容
title_list = html.xpath('//h1[@class="post-title"]/a/text()')
print(title_list)
['4.3 通过selenium 模拟浏览器抓取', '4.2 解析真实地址抓取', '第四章- 动态网页抓取 (解析真实地址 + selenium)', '《网络爬虫:从入门到实践》一书勘误', 'Hello world!']

//h1:代表选取所有<h1>子元素,“//”无论在什么位置,后面加上[@class="post-title"]表示选取<h1>中class为"post-title"的元素。/a表示选取<h1>子元素的<a>元素。/text()表示提取<a>元素中的所有文本。

XPath使用路径表达式可以在网页源代码中选取节点,它是在路径来选取的。

表达式描述
nodename选取此节点的所有子节点
/

从根节点选取

//从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置
.选取当前节点
..选取当前节点的父节点
@选取属性

四、BeautifulSoup爬虫实践:房屋价格数据

import requests
from bs4 import BeautifulSoup

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
for i in range(1, 11):
    link = 'https://beijing.anjuke.com/sale/p' + str(i) 
    r = requests.get(link, headers=headers)
    print("现在爬取的是第",i, "页")
    soup = BeautifulSoup(r.text, 'lxml')
    house_list = soup.find_all('li', class_="list-item")
    
    for house in house_list:
        name = house.find('div', class_='house-title').a.text.strip()
        print(name)
现在爬取的是第 1 页
钥匙房随时看随时签约!中高层电梯观景2居,有本,税少诚心卖
七家 精装两居 双南北通透 通风效果好 格局方正 明厨明卫
首付80万留北京 首开国企墅质现房 通州副中心给您一个家!
必卖后南仓南北通透两居 无公摊 精装修 有钥匙 上后南仓小学
昌平价格Wadi 8号线平西府Xi缺婚房大二居 买到就是赚到
九州,首地浣溪谷,南北双通透,精装两居,中层,不临街,诚售
合生70年住宅两居室 南北通透 看房方便 诚心出售
九州 付秋艳推荐 大兴采育 一层把边带花园 满五无税 诚售
万科幸福汇品质社区一层送超大花园满二年价格可商议业主急售
九州好房源把边大花园,南北通透,业主诚售。
万科幸福汇 急售精装 有钥匙 三居送花园 窦店中心繁华位置
磁各庄新机场沿线 首地浣溪谷 南北精装两居高原* 六环边

总结:解析网页有很多种方法,我们只需要选取一种方法,学会学精就可以,我觉得最重要的不是这些方法,而是如果通过网页检查找到对应的标签。

上一篇文章:动态网页爬取

下一篇文章:爬虫学习----数据存储

注意:本篇学习笔记,是总结唐松老师的《Python网络爬虫从入门到实践》这本书的内容,如果想了解书中详细内容,请自行购买

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python爬虫实例教程-代码,是一个指导如何使用Python编写爬虫的教程。下面我将用300字中文来回答这个问题。 这个教程的代码示例主要分为以下几个部分。 第一部分是爬虫的准备工作,包括安装Python和相关的第三方库,如requests、BeautifulSoup等。首先需要安装Python,并配置好相关环境变量。然后使用pip安装requests和BeautifulSoup库,这两个库是编写爬虫时常用的工具。 第二部分是使用requests库发送网络请求,获取网页的HTML源代码。首先需要导入requests库,然后使用get方法发送网络请求,传入要爬取的网页地址。之后可以通过response对象的text属性获取网页的HTML源代码。 第三部分是使用BeautifulSoup库解析HTML源代码,提取出需要的数据。首先需要导入BeautifulSoup库,然后将HTML源代码作为参数传入BeautifulSoup类的构造函数。之后可以使用BeautifulSoup对象的find、findAll等方法,根据HTML标签和属性来提取出需要的数据。 第四部分是保存爬取的数据。可以使用Python自带的文件操作函数,如open、write等,将爬取的数据保存到本地文件中。 最后,还可以通过循环、条件判断等控制结构,以及其他的Python编程技巧,对爬虫代码进行更加复杂的处理和优化。 总的来说,Python爬虫实例教程-代码提供了一个从安装环境到写爬虫代码的全过程。通过学习这些代码示例,可以掌握如何使用Python编写爬虫,以及一些常用的爬虫技巧和工具的使用。希望以上回答可以帮助到你。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值