Python 爬虫找到数据了 re & XPath & requests & Pool

2018.06.16 23:18 88浏览

字号

是的,爬虫就是为了获取数据。在获取的数据中,会有很多的冗余信息,需要在获取的数据中提取所需要的有用信息。进而联想到数据的匹配:正则表达式。接下来重点介绍的是 Python 中的两个提取数据的两个框架 re 与 XPath

一、正则表达式

正则表达式是通用的,不区分任何的语言。以下是一些比较常用的通配符:

image.png

二、re

在 re 中有三个比较重要的函数,介绍如下:

  • findall: 匹配所有符合规律的内容,返回包含结果的列表

  • Search:匹配并提取第一个符合规律的内容,返回一个正则表达式对象(object)

  • Sub :替换符合规律的内容,返回替换后的值

接下来是将一些比较常用的语法通过以上三个函数都使用以下。当然了, 在使用之前先导入 re

import re

2.1 关于点、星号与问号的使用

# 点的使用def dotFunc():# 定义一个字符串value = 'Hello, CoderHG. My name is CoderOC.'# 匹配名字names = re.findall('Coder..', value)    # 打印print(names)    # 结果 ['CoderHG', 'CoderOC']# 依次打印for name in names:print(name)# 星号的使用def starFunc():value = 'Hello, CoderHG.'name = re.findall('Coder*', value)print(name)    # 结果  ['Coder']# 问号的使用def questionFunc():value = 'Hello, CoderHG.'name = re.findall('Coder?', value)print(name)    # 结果  ['Coder']

2.2 贪心算法

主要是 .* 匹配, 代码如下:

### 2.2 贪心算法def tanxinFunc():secret_code = 'hadkfalifexxIxxfasdjifja134xxlovexx23345sdfxxyouxx8dfse'b = re.findall('xx.*xx',secret_code)print(b)    # 打印结果 ['xxIxxfasdjifja134xxlovexx23345sdfxxyouxx']

匹配的是尽量多的内容。

2.3 非贪心算法

主要是匹配 .*?匹配, 代码如下:

# 非贪心算法def notTanxinFunc():secret_code = 'hadkfalifexxIxxfasdjifja134xxlovexx23345sdfxxyouxx8dfse'b = re.findall('xx.*?xx',secret_code)print(b)    # 打印结果 ['xxIxx', 'xxlovexx', 'xxyouxx']

尽量的少,尽量的细致的去匹配

2.4 括号+非贪心算法

# 括号+非贪心算法def kuohaoNotTanxinFunc():secret_code = 'hadkfalifexxIxxfasdjifja134xxlovexx23345sdfxxyouxx8dfse'b = re.findall('xx(.*?)xx', secret_code)print(b)    # 打印结果 ['I', 'love', 'you']for text in b:print(text)

2.5 re.S 参数的作用

def huanhangFunc():s = '''sdfxxhelloxxfsdfxxworldxxasdf'''# 不带 re.S 参数d = re.findall('xx(.*?)xx', s)print(d)    # 打印结果: ['fsdf']# 带有 re.S 参数d_reS = re.findall('xx(.*?)xx',s, re.S)print(d_reS)    # 打印结果: ['he\n    llo\n    ', 'world']

加上 re.S 能匹配出带有换行的字符。

2.6 findall 与 search 结合使用

def findallAndSearchFunc():s2 = 'asdfxxIxx123xxlovexxdfd'result = re.search('xx(.*?)xx123xx(.*?)xx',s2)print(result)    # 打印结果 对象: <_sre.SRE_Match object; span=(4, 20), match='xxIxx123xxlovexx'>f = result.group(2)print(f)    # 打印结果 : loveresult = re.findall('xx(.*?)xx123xx(.*?)xx',s2)print(result)    # 打印结果 数组套元组: [('I', 'love')]f = result[0][1]print(f)    # 打印结果 :  love

2.7 sub 的使用

# sub 的使用, 替换字符串def subFunc():s = '我很想对她说: I what You.'f = re.sub('I (.*?) You.', 'I love You.', s)print(f)    # 打印结果: 我很想对她说: I love You.

三、XPath

3.1 安装 lxml

通过 pip list 指令查看是否已经安装 list。 如果没有安装,执行 pip install lxml即可。
这个东西与其他的库有所不同, 说的是 XPath, 安装的是 lxlml。在使用的时候, 直接导入:

from lxml import etree

温馨提示:按照以上的步骤如果import 的时候出错, 那么到设置中手动安装一下。

3.2 使用格式

3.2.1 套路

Selector = etree.HTML(网页源代码)
Selector.xpath(一段神奇的符号)

3.2.2 规律

    1. 树状结构

    1. 逐层展开

    1. 逐层定位

  • 4.寻找独立节点

3.2.3 语法

    1. // 定位根节点

    1. /  往下层寻找

    1. 提取文本内容:/text()

    1. 提取属性内容: /@xxxx

3.3 实例

3.3.1 常规用法

这里有一个简单的 HTML 文本, 如下:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>测试-常规用法</title></head><body><div id="content"><ul id="useful"><li>这是第一条信息</li><li>这是第二条信息</li><li>这是第三条信息</li></ul><ul id="useless"><li>不需要的信息1</li><li>不需要的信息2</li><li>不需要的信息3</li></ul><div id="url"><a href="http://jikexueyuan.com">极客学院</a><a href="http://jikexueyuan.com/course/" title="极客学院课程库">点我打开课程库</a></div></div></body></html>

现在想要提取 id = useful 中的 ui 标签中的内容, 以及 获取 a 标签中的连接,如果使用 re 的话, 那就不好办了, 尤其是提取 id = useful 中的 ui 标签中的内容,因为还有一个与之类似的 id=userless 的标签。
使用 XPath 的话, 就显得容易了, 代码如下:

# XPath 的相关用法def xpatHTML():# 获取一个与 XPath 相关的对象selector = etree.HTML(html)    # 提取文本 是数组contents = selector.xpath('//ul[@id="useful"]/li/text()')    # content = selector.xpath('//*[@id="useful"]/li/text()')# 打印获取的内容for content in contents:print(content)    # 打印结果:# 这是第一条信息# 这是第二条信息# 这是第三条信息# 提取属性links = selector.xpath('//a/@href')    for link in  links:print(link)    # 打印结果:# http://jikexueyuan.com# http://jikexueyuan.com/course/

3.3.2 特殊用法一(以相同的字符开头)

现在有以下一段 html 的文本内容:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title></title></head><body><div id="test-1">需要的内容1</div><div id="test-2">需要的内容2</div><div id="testfault">需要的内容3</div></body></html>

需要提取 id=‘test*’ 中的内容, 那么久需要使用到的的语法是这样的:

starts-with(@属性名称, 属性字符相同部分)

代码可见:

# 以相同的字符开头def startwithFunc():print('以相同的字符开头')    # 获取一个与 XPath 相关的对象selector = etree.HTML(html)    # 提取文本 是数组contents = selector.xpath('//div[starts-with(@id,"test")]/text()')    # 打印for content in contents:print(content)    # 打印结果:# 需要的内容1# 需要的内容2# 需要的内容3

3.3.3 特殊用法二(标签套标签)

有一个如下的 HTML 文本:

<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title></title></head><body><div id="test3">我左青龙,        <span id="tiger">右白虎,            <ul>上朱雀,                <li>下玄武。</li></ul>老牛在当中,        </span>龙头在胸口。    </div></body></html>

现在想要提取这样的内容:我左青龙,右白虎,上朱雀,下玄武。老牛在当中,龙头在胸口。
那么就要使用 string(.),  实现代码如下:

# 标签套标签def divdivFunc():print('标签套标签')    # 获取一个与 XPath 相关的对象selector = etree.HTML(html)    # 提取文本contents = selector.xpath('//div[@id="test3"]/text()')    # 打印print(contents)    # 打印结果: ['\n        我左青龙,\n        ', '\n        龙头在胸口。\n    ']# 这里的结果没有打印出标签中的标签的内容# 还需要这么做datas = selector.xpath('//div[@id="test3"]')    # 获取数组中的第一个元素data = datas[0]    # 获取内容info = data.xpath('string(.)')    # 字符串替换  '\n'  ->  ''content = info.replace('\n', '')    # 字符串替换  '  '  ->  ''content = content.replace(' ', '')print(content)    # 打印结果: 我左青龙,右白虎,上朱雀,下玄武。老牛在当中,龙头在胸口。

小总结

正在表达式能处理很多的问题了,但是有的时候也会遇到以上 XPath 中介绍的数据结构, 如果还是使用正则表达式的话, 就有点不简单的。以上可以看出使用 XPath 还是很简单的。

四、Python 的并行化

以一个异步获取贴吧数据为例:

#-*-coding:utf8-*-# as 的语法是将 Pool 替换成 ThreadPool 来使用from multiprocessing.dummy import Pool as ThreadPoolimport multiprocessingimport requestsimport time# 存储所有的 urlurls = []# 获取所有的 urldef getURLs():for i in range(1, 21):        # 生成连接newpage = 'http://tieba.baidu.com/p/3522395718?pn=' + str(i)        # 添加到 urls 列表中urls.append(newpage)# 爬去数据def getsource(url):requests.get(url)print(url)# 单线程获取数据def sigleFunc():startTime = time.time()    for url in  urls:getsource(url)endTime = time.time()print(u'单线程耗时' + str(endTime-startTime))# 并行处理def poolFunc():count = multiprocessing.cpu_count();print(count)startTime = time.time()pool = ThreadPool(count)results = pool.map(getsource, urls)pool.close()pool.join()endTime = time.time()print(u'耗时' + str(endTime - startTime))if __name__ == '__main__':    # 获取所有的 URLgetURLs()    # 单线程sigleFunc()    # 多线程(并行)poolFunc()

Log日志输入如下:

http://tieba.baidu.com/p/3522395718?pn=1http://tieba.baidu.com/p/3522395718?pn=2http://tieba.baidu.com/p/3522395718?pn=3http://tieba.baidu.com/p/3522395718?pn=4http://tieba.baidu.com/p/3522395718?pn=5http://tieba.baidu.com/p/3522395718?pn=6http://tieba.baidu.com/p/3522395718?pn=7http://tieba.baidu.com/p/3522395718?pn=8http://tieba.baidu.com/p/3522395718?pn=9http://tieba.baidu.com/p/3522395718?pn=10http://tieba.baidu.com/p/3522395718?pn=11http://tieba.baidu.com/p/3522395718?pn=12http://tieba.baidu.com/p/3522395718?pn=13http://tieba.baidu.com/p/3522395718?pn=14http://tieba.baidu.com/p/3522395718?pn=15http://tieba.baidu.com/p/3522395718?pn=16http://tieba.baidu.com/p/3522395718?pn=17http://tieba.baidu.com/p/3522395718?pn=18http://tieba.baidu.com/p/3522395718?pn=19http://tieba.baidu.com/p/3522395718?pn=20单线程耗时18.2060580253601078http://tieba.baidu.com/p/3522395718?pn=3http://tieba.baidu.com/p/3522395718?pn=8http://tieba.baidu.com/p/3522395718?pn=2http://tieba.baidu.com/p/3522395718?pn=5http://tieba.baidu.com/p/3522395718?pn=6http://tieba.baidu.com/p/3522395718?pn=7http://tieba.baidu.com/p/3522395718?pn=4http://tieba.baidu.com/p/3522395718?pn=1http://tieba.baidu.com/p/3522395718?pn=14http://tieba.baidu.com/p/3522395718?pn=13http://tieba.baidu.com/p/3522395718?pn=10http://tieba.baidu.com/p/3522395718?pn=12http://tieba.baidu.com/p/3522395718?pn=9http://tieba.baidu.com/p/3522395718?pn=15http://tieba.baidu.com/p/3522395718?pn=11http://tieba.baidu.com/p/3522395718?pn=16http://tieba.baidu.com/p/3522395718?pn=19http://tieba.baidu.com/p/3522395718?pn=18http://tieba.baidu.com/p/3522395718?pn=20http://tieba.baidu.com/p/3522395718?pn=17耗时2.678765058517456

结论: 使用并行处理, 可以节省不少的时间。

Python 爬虫找到数据了 re XPath requests Pool相关推荐

  1. Python爬虫以及数据可视化分析

    Python爬虫以及数据可视化分析之Bilibili动漫排行榜信息爬取分析 简书地址:https://www.jianshu.com/u/40ac87350697 简单几步,通过Python对B站番剧 ...

  2. python 爬虫与数据可视化

    python 爬虫与数据可视化 1.引言 Web已经成为日新月异迅速发展的网络信息技术中的信息载体,如何有效地提取和利用搜索引擎获得互联网最有用的.可以免费公开访问的数据集,查找用户所需的价值数据或者 ...

  3. 小白学 Python 爬虫(20):Xpath 进阶

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  4. python爬虫及数据可视化分析

    python爬虫及数据可视化分析 1.前言 2.数据爬取 2.1定位到爬取数据 2.2爬虫实现方法 3.数据可视化分析 3.1将短文学网的各类文章做一个统计 3.2对某一类文章进行分析 1.前言 本篇 ...

  5. Python爬虫+数据分析+数据可视化(分析《雪中悍刀行》弹幕)

    Python爬虫+数据分析+数据可视化(分析<雪中悍刀行>弹幕) 哔哔一下 爬虫部分 代码部分 效果展示 数据可视化 代码展示 效果展示 视频讲解 福利环节 哔哔一下 雪中悍刀行兄弟们都看 ...

  6. Python爬虫——Ajax数据爬取

    前言 有时候我们在用requests抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面数据,但使用requests得到的结果并没有.这是因为在requests获得 ...

  7. python爬虫之数据爬取项目实例

    python爬虫之数据爬取项目实例 一.scrapy数据爬取 (一)前期准备 (二)目标: (三)步骤: 1.创建项目: 2.创建爬虫: 3.打开项目: 4.创建启动程序: 5.编写爬虫: 6.启动测 ...

  8. python爬虫数据提取_入门Python爬虫——提取数据篇

    原标题:入门Python爬虫--提取数据篇 作者: 李菲 来源:人工智能学习圈 前言 在提取数据这一环节,爬虫程序会将我们所需要的数据提取出来.在上一篇文章<入门Python爬虫 -- 解析数据 ...

  9. python 爬虫及数据可视化展示

    python 爬虫及数据可视化展示 学了有关python爬虫及数据可视化的知识,想着做一些总结,加强自己的学习成果,也能给各位小伙伴一些小小的启发. 1.做任何事情都要明确自己的目的,想要做什么,打算 ...

最新文章

  1. Apache配置--用户认证(针对目录访问)-update2015-05-02
  2. 用于文档上下文感知推荐的卷积矩阵分解
  3. vue2实现自定义样式radio单选框
  4. 更改mysql最大连接数
  5. 自从装了windows神器,再也不用羡慕mac了
  6. ASP.NET Core开发-Docker部署运行
  7. C++之delete常见错误总结
  8. oracle两个表合并 sql,如何创建从两个表(Oracle DBMS)生成“合并”数据集的Select SQL语句?...
  9. flash builder4.7 for Mac升级AIRSDK详解
  10. java uuid静态方法_Java UUID equals()方法与示例
  11. matlab拔河比赛_拔河比赛
  12. c语言加密shell脚本,shell脚本加密
  13. 【node】---记忆内容
  14. 太火了,这些牛逼的Java代码技巧,肯定能让你目瞪口呆!
  15. 市场对php的需求分析,PHP 留言板功能需求分析
  16. python双人贪吃蛇游戏
  17. SVN常用基本命令windows
  18. 怎样在WORD里输入国际音标
  19. java-net-php-python-springboot学校在线作业考试系统计算机毕业设计程序
  20. 深度搜索处理问题的关键 --- 做leetcode深度搜索类题目小结

热门文章

  1. 在Mac下使用Charles抓取Android 7.0以上的Https请求
  2. Android Stuido环境搭建
  3. js 中的 Event Loop 以及 宏任务 与 微任务
  4. 修炼魅力女人“诱惑”术
  5. chrome如何添加其他搜索引擎
  6. 几种典型的无线传播模型
  7. 国际会议英语口语100句
  8. all index range ref eq_ref const system 索引type说明
  9. 2020年第四届计算机检测维修与数据恢复国赛模拟比赛
  10. React学习(六)-React中组件的数据-state