常用的类库为lxml, BeautifulSoup, re(正则)

以获取豆瓣电影正在热映的电影名为例,url='https://movie.douban.com/cinema/nowplaying/beijing/'

网页分析

部分网页源码

<ul class="lists">
<li
id="3878007"
class="list-item"
data-title="海王"
data-score="8.2"
data-star="40"
data-release="2018"
data-duration="143分钟"
data-region="美国 澳大利亚"
data-director="温子仁"
data-actors="杰森·莫玛 / 艾梅柏·希尔德 / 威廉·达福"
data-category="nowplaying"
data-enough="True"
data-showed="True"
data-votecount="105013"
data-subject="3878007"
>

分析可知我们要的电影名称信息在li标签的data-title属性里

下面开始写代码

爬虫源码展示

import requests
from lxml import etree # 导入库
from bs4 import BeautifulSoup
import re import time # 定义爬虫类
class Spider():
def __init__(self):
self.url = 'https://movie.douban.com/cinema/nowplaying/beijing/' self.headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
r = requests.get(self.url,headers=self.headers)
r.encoding = r.apparent_encoding
self.html = r.text def lxml_find(self):
'''用lxml解析'''
start = time.time() # 三种方式速度对比
selector = etree.HTML(self.html) # 转换为lxml解析的对象
titles = selector.xpath('//li[@class="list-item"]/@data-title') # 这里返回的是一个列表
for each in titles:
title = each.strip() # 去掉字符左右的空格
print(title)
end = time.time()
print('lxml耗时', end-start) def BeautifulSoup_find(self):
'''用BeautifulSoup解析'''
start = time.time()
soup = BeautifulSoup(self.html, 'lxml') # 转换为BeautifulSoup的解析对象()里第二个参数为解析方式
titles = soup.find_all('li', class_='list-item')
for each in titles:
title = each['data-title']
print(title)
end = time.time()
print('BeautifulSoup耗时', end-start) def re_find(self):
'''用re解析'''
start = time.time()
titles = re.findall('data-title="(.+)"',self.html)
for each in titles:
print(each)
end = time.time()
print('re耗时', end-start) if __name__ == '__main__':
spider = Spider()
spider.lxml_find()
spider.BeautifulSoup_find()
spider.re_find()

输出结果

海王
无名之辈
无敌破坏王2:大闹互联网
狗十三
惊涛飓浪
毒液:致命守护者
憨豆特工3
神奇动物:格林德沃之罪
恐龙王
老爸102岁
生活万岁
进击的男孩
摘金奇缘
亡命救赎
一百年很长吗
云上日出
谁是坏孩子
照相师
缘·梦
网络谜踪
龙猫
印度合伙人
绿毛怪格林奇
最萌警探
春天的马拉松
lxml耗时 0.007623910903930664
海王
无名之辈
无敌破坏王2:大闹互联网
狗十三
惊涛飓浪
毒液:致命守护者
憨豆特工3
神奇动物:格林德沃之罪
恐龙王
老爸102岁
生活万岁
进击的男孩
摘金奇缘
亡命救赎
一百年很长吗
超时空大冒险
天渠
爱不可及
二十岁
你好,之华
冒牌搭档
铁甲战神
克隆人
恐怖快递
中国蓝盔
阿凡提之奇缘历险
名侦探柯南:零的执行人
为迈克尔·杰克逊铸造雕像
再见仍是朋友
心迷宫
淡蓝琥珀
阿拉姜色
两个俏公主
云上日出
谁是坏孩子
照相师
缘·梦
网络谜踪
龙猫
印度合伙人
绿毛怪格林奇
最萌警探
春天的马拉松
BeautifulSoup耗时 0.061043500900268555
海王
无名之辈
无敌破坏王2:大闹互联网
狗十三
惊涛飓浪
毒液:致命守护者
憨豆特工3
神奇动物:格林德沃之罪
恐龙王
老爸102岁
生活万岁
进击的男孩
摘金奇缘
亡命救赎
一百年很长吗
超时空大冒险
天渠
爱不可及
二十岁
你好,之华
冒牌搭档
铁甲战神
克隆人
恐怖快递
中国蓝盔
阿凡提之奇缘历险
名侦探柯南:零的执行人
为迈克尔·杰克逊铸造雕像
再见仍是朋友
心迷宫
淡蓝琥珀
阿拉姜色
两个俏公主
云上日出
谁是坏孩子
照相师
缘·梦
网络谜踪
龙猫
印度合伙人
绿毛怪格林奇
最萌警探
春天的马拉松
re耗时 0.0004856586456298828

代码说明

1. lxml

lxml是通过xpath来查找

使用前需使用调用ertee.HTML()方法('()'内填HTML代码)生成一个可查找的对象

常用xpath语法如下

// 两个斜杠为向下查找孙子标签

/ 一个斜杠为查找直接儿子标签

[] 方括号内填标签属性,如查找class属性为name的a标签,格式为a[@class="name"]

/text() 取出标签的内容,如查找网页中的 <a class="name">KAINHUCK</a> 中的KAINHUCK,格式为//a[@class="name"]/text()

/@attr 取出标签的属性,如查找网页中的 <a class="name">KAINHUCK</a> 中的class属性值name,格式为//a[@class="name"]/@class

2. BeautifulSoup

使用前需先将HTML转换为课查找对象,格式为

BeautifulSoup(html, 'lxml')

html 为HTML代码, 后面的参数为转换方法(其他方法有'html.parser' , 'html5lib', 推荐使用'lxml')

查找方法

info = find('a', id='kain') 查找第一个id属性为kain的a标签,并存进info变量中(其他标签同理)

find_all('a', class_='name') 查找所有class属性为name的a标签(注:class属性需写成'class_')

info.p.text 获取第一个id属性为kain的a标签下的p标签的内容(info为上面例子里的info,其他同理)

info.p['name'] 获取第一个id属性为kain的a标签下的p标签的name属性值(info为上面例子里的info,其他同理)

当代码中有很多同级标签时

<p class='info-list'>
<a class='name'>text1</a>
<a class='name'>text2</a>
<a class='name'>text3</a>
<a class='name'>text4</a>
</p>

示例代码如下

from bs4 import BeautifulSoup

html = '''
<p class='info-list'>
<a class='name'>text1</a>
<a class='name'>text2</a>
<a class='name'>text3</a>
<a class='name'>text4</a>
</p>
'''
soup = BeautifulSoup(html, 'lxml')
texts = soup.find('p', class_='info-list')
print(texts.contents[1].text) # 输出text1
print(texts.contents[2].text) # 输出text2
print(texts.contents[3].text) # 输出text3
print(texts.contents[4].text) # 输出text4

注意:不是从0开始

3. re(正则表达式)

正则表达式内容较多,大家可以参考这里

总结

使用lxml查找时可以在目标网页按F12调出开发者窗口然后再在按Ctrl+f查找,在查找栏里输入你的xpath语法可以检查是否能找到对应内容

可以从看例子的输出中看出三种方法的速度

lxml耗时 0.007623910903930664

BeautifulSoup耗时 0.061043500900268555

re耗时 0.0004856586456298828

对以上三种最常用的解析网页的方法做个对比

lxml BeautifulSoup re
语法难易度 简单 简单 复杂
查找速度 较快

综上,对于网页内容的解析,这里推荐新手使用lxml方法,而对速度有要求就使用正则表达式(入门有点困难)

Python爬虫之解析网页的更多相关文章

  1. python网络爬虫之解析网页的BeautifulSoup(爬取电影图片)[三]

    目录 前言 一.BeautifulSoup的基本语法 二.爬取网页图片 扩展学习 后记 前言 本章同样是解析一个网页的结构信息 在上章内容中(python网络爬虫之解析网页的正则表达式(爬取4k动漫图 ...

  2. python爬虫数据解析之BeautifulSoup

    BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. BeautfulSoup是python爬虫三 ...

  3. python爬虫——爬取网页数据和解析数据

    1.网络爬虫的基本概念 网络爬虫(又称网络蜘蛛,机器人),就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序.只要浏览器能够做的事情,原则上,爬虫都能够做到. 2 ...

  4. python网络爬虫之解析网页的XPath(爬取Path职位信息)[三]

    目录 前言 XPath的使用方法 XPath爬取数据 后言 @(目录) 前言 本章同样是解析网页,不过使用的解析技术为XPath. 相对于之前的BeautifulSoup,我感觉还行,也是一个比较常用 ...

  5. Python爬虫之三种网页抓取方法性能比较

    下面我们将介绍三种抓取网页数据的方法,首先是正则表达式,然后是流行的 BeautifulSoup 模块,最后是强大的 lxml 模块. 1. 正则表达式   如果你对正则表达式还不熟悉,或是需要一些提 ...

  6. 使用notepad++学习python爬虫,print网页中文乱码问题

    今天学习使用python爬虫的时候发现爬到的网页中文会乱码,一直网上搜索解决办法,一个一个试验过去,发现还是乱码,然后我就开始使用其它方法测试,用python自带的编辑器打开是正常的,发现是notep ...

  7. python爬虫数据解析之正则表达式

    爬虫的一般分为四步,第二个步骤就是对爬取的数据进行解析. python爬虫一般使用三种解析方式,一正则表达式,二xpath,三BeautifulSoup. 这篇博客主要记录下正则表达式的使用. 正则表 ...

  8. python爬虫--数据解析

    数据解析 什么是数据解析及作用 概念:就是将一组数据中的局部数据进行提取 作用:来实现聚焦爬虫 数据解析的通用原理 标签定位 取文本或者属性 正则解析 正则回顾 单字符: . : 除换行以外所有字符 ...

  9. python爬虫三大解析库之XPath解析库通俗易懂详讲

    目录 使用XPath解析库 @(这里写自定义目录标题) 使用XPath解析库 1.简介   XPath(全称XML Path Languang),即XML路径语言,是一种在XML文档中查找信息的语言. ...

随机推荐

  1. jmeter用Stepping Thread Group 递增并发数

    jmeter安装插件Stepping Thread Group 如图所示设置的时候,本以为是每2秒 按 1 2 3 4 递增的,总共请求应该是10个,可是运行后却请求了几十个. 这个是有关线程数是否就 ...

  2. Linux ---- 查看当前TCP连接数

    一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议 ...

  3. java 加法变乘法

    加法变乘法 我们都知道:1+2+3+ - + 49 = 1225 (1) 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+...+10*11+12+...+27*28 ...

  4. 2-10 就业课(2.0)-oozie:6、通过oozie执行mr任务,以及执行sqoop任务的解决思路

    执行sqoop任务的解决思路(目前的问题是sqoop只安装在node03上,而oozie会随机分配一个节点来执行任务): ======================================= ...

  5. Dive into re Module in Python

    Dive into RE in Python Standard re module in python is powerful to handle text manipulation,such as ...

  6. springcloud--ribbo(负载均衡)

    ribbo:是Netflix公司开源的一个负载均衡的项目,是一个客户端负载均衡器,运行在客户端上. 实际运用案例(基于springcloud入门案例): 一.新建Module:springcloud- ...

  7. lvm 通过扩容本身磁盘容量扩容

    场景:sdb之前是3G容量,现在扩容了sdb的容量到8G.现在把新扩容的5G容量扩展到现有的逻辑卷中 [root@localhost ~]# pvresize /dev/sdb  Physical v ...

  8. springboot#interceptor

    _ 拦截器相对与过滤器Filter 而言,拦截器是spring中的概念.过滤器是servlet中的概念.在spring中肯定是优先使用拦截器Interceptor的. public class My1 ...

  9. ActiveMQ持久化机制和JMS可靠消息

    1.ActiveMQ持久化机制 1.1 JDBC将数据持久化到数据库 1.2 AMQ生成日志文件 1.3 KahaDB:本次磁盘生成数据文件(默认) 1.4 LevelDB:谷歌K/V数据库 1.5 ...

  10. SpringBoot 系列教程之事务隔离级别知识点小结

    SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...