作者 | 陈熹

来源 | 早起Python

头图 | 下载于视觉中国

在使用Python本爬虫采集数据时,一个很重要的操作就是如何从请求到的网页中提取数据,而正确定位想要的数据又是第一步操作。本文将对比几种 Python 爬虫中比较常用的定位网页元素的方式供大家学习:

1.传统 BeautifulSoup 操作

2.基于 BeautifulSoup 的 CSS 选择器(与 PyQuery 类似)

3.XPath

4.正则表达式

参考网页是当当网图书畅销总榜

http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1

我们以获取第一页 20 本书的书名为例,先确定网站没有设置反爬措施,是否能直接返回待解析的内容:

import requestsurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
print(response)

仔细检查后发现需要的数据都在返回内容中,说明不需要特别考虑反爬举措。

审查网页元素后可以发现,书目信息都包含在 li 中,从属于 classbang_list clearfix bang_list_modeul 中。

进一步审查也可以发现书名在的相应位置,这是多种解析方法的重要基础

传统 BeautifulSoup 操作

经典的 BeautifulSoup 方法借助 from bs4 import BeautifulSoup,然后通过 soup = BeautifulSoup(html, "lxml") 将文本转换为特定规范的结构,利用 find系列方法进行解析,代码如下:

import requests
from bs4 import BeautifulSoupurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef bs_for_parse(response):soup = BeautifulSoup(response, "lxml")li_list = soup.find('ul', class_='bang_list clearfix bang_list_mode').find_all('li') # 锁定ul后获取20个lifor li in li_list:title = li.find('div', class_='name').find('a')['title'] # 逐个解析获取书名print(title)if __name__ == '__main__':bs_for_parse(response)

成功获取了 20 个书名,有些书面显得冗长可以通过正则或者其他字符串方法处理,本文不作详细介绍。

基于 BeautifulSoup 的 CSS 选择器

这种方法实际上就是 PyQuery 中 CSS 选择器在其他模块的迁移使用,用法是类似的。关于 CSS 选择器详细语法可以参考:http://www.w3school.com.cn/cssref/css_selectors.asp由于是基于 BeautifulSoup 所以导入的模块以及文本结构转换都是一致的:

import requests
from bs4 import BeautifulSoupurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef css_for_parse(response):soup = BeautifulSoup(response, "lxml") print(soup)if __name__ == '__main__':css_for_parse(response)

然后就是通过soup.select 辅以特定的 CSS 语法获取特定内容,基础依旧是对元素的认真审查分析:

import requests
from bs4 import BeautifulSoup
from lxml import htmlurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef css_for_parse(response):soup = BeautifulSoup(response, "lxml")li_list = soup.select('ul.bang_list.clearfix.bang_list_mode > li')for li in li_list:title = li.select('div.name > a')[0]['title']print(title)if __name__ == '__main__':css_for_parse(response)

XPath

XPath 即为 XML 路径语言,它是一种用来确定 XML 文档中某部分位置的计算机语言,如果使用 Chrome 浏览器建议安装 XPath Helper 插件,会大大提高写 XPath 的效率。

之前的爬虫文章基本都是基于 XPath,大家相对比较熟悉因此代码直接给出:

import requests
from lxml import htmlurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef xpath_for_parse(response):selector = html.fromstring(response)books = selector.xpath("//ul[@class='bang_list clearfix bang_list_mode']/li")for book in books:title = book.xpath('div[@class="name"]/a/@title')[0]print(title)if __name__ == '__main__':xpath_for_parse(response)

正则表达式

如果对 HTML 语言不熟悉,那么之前的几种解析方法都会比较吃力。这里也提供一种万能解析大法:正则表达式,只需要关注文本本身有什么特殊构造文法,即可用特定规则获取相应内容。依赖的模块是 re。

首先重新观察直接返回的内容中,需要的文字前后有什么特殊:

import requests
import reurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).text
print(response)

观察几个数目相信就有答案了:<div class="name"><a href="http://product.dangdang.com/xxxxxxxx.html" target="_blank" title="xxxxxxx">书名就藏在上面的字符串中,蕴含的网址链接中末尾的数字会随着书名而改变。

分析到这里正则表达式就可以写出来了:

import requests
import reurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef re_for_parse(response):reg = '<div class="name"><a href="http://product.dangdang.com/\d+.html" target="_blank" title="(.*?)">'for title in re.findall(reg, response):print(title)if __name__ == '__main__':re_for_parse(response)

可以发现正则写法是最简单的,但是需要对于正则规则非常熟练。所谓正则大法好!

小结

当然,不论哪种方法都有它所适用的场景,在真实操作中我们也需要在分析网页结构来判断如何高效的定位元素,最后附上本文介绍的四种方法的完整代码,大家可以自行操作一下来加深体会。

import requests
from bs4 import BeautifulSoup
from lxml import html
import reurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
response = requests.get(url).textdef bs_for_parse(response):soup = BeautifulSoup(response, "lxml")li_list = soup.find('ul', class_='bang_list clearfix bang_list_mode').find_all('li')for li in li_list:title = li.find('div', class_='name').find('a')['title']print(title)def css_for_parse(response):soup = BeautifulSoup(response, "lxml")li_list = soup.select('ul.bang_list.clearfix.bang_list_mode > li')for li in li_list:title = li.select('div.name > a')[0]['title']print(title)def xpath_for_parse(response):selector = html.fromstring(response)books = selector.xpath("//ul[@class='bang_list clearfix bang_list_mode']/li")for book in books:title = book.xpath('div[@class="name"]/a/@title')[0]print(title)def re_for_parse(response):reg = '<div class="name"><a href="http://product.dangdang.com/\d+.html" target="_blank" title="(.*?)">'for title in re.findall(reg, response):print(title)if __name__ == '__main__':# bs_for_parse(response)# css_for_parse(response)# xpath_for_parse(response)re_for_parse(response)

更多精彩推荐
☞明年,我要用 AI 给全村写对联☞Ant Design 遭删库!☞每年节省170万美元的文档预览费用,借助机器学习的DropBox有多强?☞三年投 1000 亿,达摩院何以仗剑走天涯?
点分享点收藏点点赞点在看

对比四种爬虫定位元素方法,你更爱哪个?相关推荐

  1. python爬虫详细步骤-Python爬虫的两套解析方法和四种爬虫实现过程

    对于大多数朋友而言,爬虫绝对是学习 python 的最好的起手和入门方式.因为爬虫思维模式固定,编程模式也相对简单,一般在细节处理上积累一些经验都可以成功入门.本文想针对某一网页对 python 基础 ...

  2. 逐步认识C#四种判断相等的方法

    C#有四种判断相等的方法?不少人看到这个标题,会对此感到怀疑.事实上确是如此,.Net提供了ReferenceEquals.静态Equals,具体类型的Equals以及==操作符这四个判等函数.但是这 ...

  3. 身在天津的宝妈有福了,2021四种飞速涨粉方法第一手消息。

    身在天津的宝妈有福了,2021四种飞速涨粉方法第一手消息. 在dy短视频如果你的粉丝不到1000就不要想着赚钱了.因为dy短视频一千粉是很多福利的门槛. 所以今天就教天津的你四种快速涨到一千粉的方法, ...

  4. WindowsServer2012史记7-茴香豆的五种写法和四种”显示计算机”的方法

    消失的"计算机"? [这周九叔工作比较忙,还有其他琐事缠身,因此SystemCenter2012SP1系列的发布稍慢,抱歉了各位.] 众所周知,WindowsServer2012和 ...

  5. C#四种相等性判断方法 equals,referenceEquals

    C#中的ReferenceEquals.Equals以及== C#中有一共有四种相等性判断方法: //Object中定义的三个方法 public static bool ReferenceEquals ...

  6. python单例模式继承_Python四种实现单例模式的方法

    在这之前,先了解super()和__new__()方法 super()方法: 返回一个父类或兄弟类类型的代理对象,让你能够调用一些从继承过来的方法. 它有两个典型作用: a. 在单继承的类层次结构中, ...

  7. python selenium定位元素方法_[原创] python selenium 元素定位方法封装

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 写好了公用的调用类,接下来就按照pageobject的设计模式写一下基本的元素定位方法,此处我们需要对python的方法传参有所了解,没有自信的同学可以返 ...

  8. java中高效遍历list_Java中四种遍历List的方法总结(推荐)

    实例如下: package com.ietree.basic.collection.loop; import java.util.ArrayList; import java.util.Iterato ...

  9. A*寻路中第四种烘培寻路方法Recast Mesh方法:

    A*寻路中第四种烘培寻路方法Recast Mesh方法: 全地形烘培

最新文章

  1. Python-OpenCV 杂项(二): 鼠标事件
  2. 最简单实现多线程的方法(Thread)
  3. Mysql 去除 特定字符后面的所有字符串
  4. kafka基本管理操作命令
  5. 程序员经验分享:Android高级工程师系列学习路线介绍,面试必备
  6. Raspberry Pi 学习笔记之一
  7. shell - 查看天气
  8. sysV init服务脚本(入门级)
  9. 菲尼克斯电源模块的安装
  10. 【EXLIBRIS】#小词旮旯# 002 Rape
  11. 肥猫学习笔记---C语言数据结构与算法(一)-----栈
  12. startx 启动过程
  13. OpenCV开发笔记(五十二):红胖子8分钟带你深入了解直方图对比匹配(图文并茂+浅显易懂+程序源码)
  14. 微星Z370M主板参数
  15. 【70后、80后、90后嘚啵嘚】招募特约评论员啦!
  16. 关于文献HEVC-The New Glod Standard For Video Compress的理解
  17. 猫眼电影爬虫和数据分析
  18. c# socket套接字
  19. Windows批处理修改文件名拼接日期
  20. c语言malloc申请三维数组,C语言malloc函数为一维,二维,三维数组分配空间

热门文章

  1. js数组指定位置添加删除
  2. 什么是类型别名?什么是潜在类型?
  3. 04 集成学习 - Boosting - AdaBoost算法构建
  4. 归于软银帐下,ARM需要接受的变与不变
  5. 有关GetPrivateProfileString的使用方法
  6. Linux supervisor守护进程的安装和使用
  7. 澳洲服务器拳头账号怎么注册,lol手游东南亚服拳头账号注册教程 东南亚服怎么注册拳头账号[多图]...
  8. java 日志 生成_Java日志(转)
  9. java绘图之Graphics类
  10. 洛谷:P3950 部落冲突