精通Python爬虫-03-狩猎大师

声明:

本系列文章原创于慕课网,作者秋名山车神,任何人不得以任何形式在不经作者允许的情况下,进行任何形式的印刷以及销售,转载需注明出处及此声明。

本系列文章更新至少每周一更,将涉及Python爬虫基础,Requests,Scrapy等主流爬虫技术。同时会介绍图片验证码,语音验证码的识别以及我自己设计的一个高并发可扩展易维护的集群爬虫架构。

对文章有任何问题请在下面留言,我会不定期的回复大家。

人非圣贤,如果文章有错别字请大家自行区分或指正出来,我将不定期修改错误的地方。

本系列能否持久更新下去离不开大家的支持与鼓励,以及对原创版权的尊重。

作者想说的话

最近一段时间特别的忙,事情也很多。有几家出版社找着写书,都让我给推了,昨天闲着没事在翻慕课网的手记时,发现了这个系列的文章。看到那么多人浏览,那么多人评论让快点更新,我觉得不能让大家失望,所以我开始更新了。

我想做的事情很很普通,就是希望我所知道的技术能够以一种力所能及的方式带给大家,我希望慕课网是一个积极进取的社区,每个人都能毫无保留的对待别人。也希望我做的这件普通的事情,能够帮助到每一个想学习python,学习爬虫的人。谢谢大家的支持。

大师的嗅觉

在上一章中,我们已经学习了如何使用 urllib 来从网络上获取信息,这一章我们来学习如果从这些信息中提取我们想要的内容。

依然以我们的慕课网为例,顺便让我们回顾一下上一章的代码。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib.request

# 创建一个Request对象
req = urllib.request.Request(‘http://www.imooc.com‘)

# 使用Request对象发送请求
response = urllib.request.urlopen(req)

print(response.read())

如果运行上面的代码,就可以看到慕课网首页的静态代码了,也就是我们通常所说的HTML代码。

那这么多的数据,我们怎么能从中获取到想要的内容呢?比如我们想要获取慕课网首页实战推荐里面所有推荐的实战课名称,该怎么办呢?

此时我们就可以使用另外一个库 BeautifulSoup

安装BeautifulSoup

打开我们的命令行工具,输入:

pip install beautifulsoup4==4.6.0

如果你那里下载的速度特别慢,可以使用下面这条命令,指定本次使用豆瓣的pip镜像源来安装:

pip install beautifulsoup4==4.6.0 -i https://pypi.douban.com/simple

看到如下的信息就表示安装成功了:

Successfully installed beautifulsoup4-4.6.0

有的小伙伴可能还会看到一些黄色的文字:

You are using pip version 9.0.1, however version 10.0.1 is available.
You should consider upgrading via the ‘python -m pip install --upgrade pip‘ command.

这是说我们的pip版本太低了,提示我们可以使用 python -m pip install --upgrade pip 这条命令来升级到最新版本,一般不需要升级,如果想要升级的可以使用这条命令,升级以后就不会再出这个提示了。

在实战中学习

不用读系列:我并不想把本教程做成一个官方文档,或者是像其他书那样,把官方文档抄下来。这样又有什么意义呢?学了以后还是不知道怎么应用,所以我希望每一个库我们都是通过一个小项目来学习的,用到的每一个方法我都会详细的说明。而用不到的方法,它都用不到了,我们还学它干嘛?

大家跟着我一步一步学习怎么狩猎吧

首先我们打开慕课网的首页:https://www.imooc.com

建议使用Chrome浏览器

然后找到我们的实战推荐,在其中一个推荐的实战课图片上,右键点击图片,选择检查。

然后会打开浏览器的开发者工具,如果还不知道这个工具怎么用的,大家可以去看一下我的免费课程:

浏览器开发者工具使用技巧

接着我们选择开发者工具上面的选择器,使用鼠标左键点击我们想要获取的地方:

可以看到下面的代码就是我们想要获取的内容:

<h3 class="course-card-name">全网最热Python3入门+进阶 更快上手实际开发</h3>

那么其他的几个也是这样的吗?重复上面的步骤点击每个实战推荐的名字,看到如下结果:

第一个狩猎技巧

想要获取同类型的内容,就寻找他们相同的部分。

那么上面的实战推荐中,很显然他们相同的部分就是 <h3 class="course-card-name"></h3>,那接下来就直接修改上面的代码来试着获取这部分的内容。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib.request
# 导包
from bs4 import BeautifulSoup

# 创建一个Request对象
req = urllib.request.Request(‘http://www.imooc.com‘)

# 使用Request对象发送请求
response = urllib.request.urlopen(req)

soup = BeautifulSoup(response.read())
course_names = soup.find_all(‘h3‘, {‘class‘:‘course-card-name‘})

print(course_names)

from bs4 import BeautifulSoup 这句代码呢,意思就是从bs4这个模块里,导入我们的 BeautifulSoup 方法,没什么其他的含义。

BeautifulSoup() 方法接收两个参数,第一个参数是一个str类型的,就是我们获取到的HTML代码。第二个参数也是一个str类型的,表示我们希望使用哪个库来解析HTML的代码,常用的都 html.parser 和 lxml,其中lxml 效率更高一些。而我们上面的代码并没有指定第二个参数,所以它会输出一个警告信息。

UserWarning: No parser was explicitly specified, so I‘m using the best available HTML parser for this system ("lxml"). This usually isn‘t a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

The code that caused this warning is on line 5 of the file C:\dream\python\Anaconda3\Scripts\ipython-script.py. To get rid of this warning, change code that looks like this:

BeautifulSoup(YOUR_MARKUP})

to this:

BeautifulSoup(YOUR_MARKUP, "lxml")

markup_type=markup_type))

关键在于倒数第二行 BeautifulSoup(YOUR_MARKUP, "lxml"),这里提示的很明显,让我们增加第二个参数 lxml。当然了,这是因为我的电脑里安装了 lxml 库,没有安装的小伙伴,这里提示的可能是 html.parser,不管提示的是什么,你都按照BeautifulSoup提示你的来进行修改就可以了~

我这里按照提示修改以后的那句代码就成了:

soup = BeautifulSoup(response.read(), "lxml")

这个方法还会给我们返回一个bs4.BeautifulSoup的对象,我们可以使用一个变量来接收,这个变量可以是任意名字,这里我们用 soup 来表示。

soup.find_all() 这个方法接收两个参数,代表从 soup 这个对象里,搜索全部符合条件的内容。第一个参数是str类型的,表示我们要从哪个HTML标签中获取,这里我们是要从 h3 这个标签里获取。第二个dict类型的,接收key和value的键值对。代表我们要获取的这个h3标签,有那些属性可以来标识它。

<h3 class="course-card-name">全网最热Python3入门+进阶 更快上手实际开发</h3>

可以看到我们想获取的h3标签,只有一个class属性,那第二个参数就是:

{"class": "course-card-name"}

该方法返回一个 bs4.element.ResultSet 类型的对象,类似于我们python的list列表,我们可以像操作列表一样来操作这个对象。同样使用一个变量去接收它。

最终上面的代码运行以后,可能看到如下的结果:

[<h3 class="course-card-name">前端进阶:响应式开发与常用框架</h3>,
 <h3 class="course-card-name">揭秘一线互联网企业 前端JavaScript高级面试</h3>,

...省略N条...

 <h3 class="course-card-name">Python Flask 构建微电影视频网站</h3>,
 <h3 class="course-card-name">AWS云-深度学习&amp;amp;机器学习的AI业务应用</h3>]

提示:由于慕课网是不断在更新的,所以当你看到这篇教程的时候,相关的内容可能已经更换了名称,比如class不叫course-card-name。我希望你能够自己修改上面的代码,来达到符合你看到教程时,慕课网的样子。

我们发现,结果和我们预想的不太一样,这是为什么呢?我们再次回到慕课网,右键在网页空白的部分单击,然后选择查看网页源码:

然后在弹出来的窗口中,按下 ctrl + f 的组合快捷键,接着搜索 course-card-name

嗯,我相信大家知道组合键的意思就是先按下键盘上的 Ctrl 键,然后不松开这个键的情况下,再按键盘上的 F 键。

看到的搜索结果如下:

出现了76个搜索结果,这是为什么呢?我们明明只是想获取实战推荐里面的课程名称,为什么出现了这么多的搜索结果?

简单思考一下我们就可以知道,我们刚才搜索是从 response.read() 里面搜索的,这代表了整个慕课网首页的所有内容。而慕课网所有的课程名称,使用的都是下面的样式:

<h3 class="course-card-name"></h3>

所以我们不仅获取了实战推荐的课程名称,还获取了其他不想要的课程名称。

爬虫并不是获取的越多越好,而是精准获取我们想要的数据,其他不想要的数据越少越好。

那么很显然,是我们狩猎的范围太大了,试着来缩小我们的狩猎范围吧。

同样使用浏览器的开发者工具,慢慢的移动我们的鼠标,直到鼠标指向的内容,刚好包裹我们想要获取的那一部分。

如图所示,最终我们指向了一个div的标签,它覆盖了我们想要获取的所有内容,而没有覆盖其他我们不想获取的内容。并且这个div也有一个class属性,通过上面学习到的,来修改一下我们的代码,看看是不是能达到我们的目的。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib.request
# 导包
from bs4 import BeautifulSoup

# 创建一个Request对象
req = urllib.request.Request(‘http://www.imooc.com‘)

# 使用Request对象发送请求
response = urllib.request.urlopen(req)

soup = BeautifulSoup(response.read(), "lxml")

# 先获取我们刚才找到的div
course_div = soup.find_all(‘div‘, {‘class‘:‘clearfix types-content‘})

# 再从我们的div里获取想要的内容
course_names = course_div.find_all(‘h3‘, {‘class‘:‘course-card-name‘})

# 结果是否是我们想要的呢?
print(course_names)

结果就报错了~

AttributeError: ResultSet object has no attribute ‘find_all‘. You‘re probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?

其实大家看到报错,不要害怕,要慢慢的看这个报错的内容,一般报错都是从倒数第一行开始看的,也只有倒数第一行往往才是有用的东西。

那么上面的这个报错很显然,find_all()方法返回的是一个ResultSet对象,这个对象不具有find_all()方法,所以在我们下面使用 course_div.find_all(‘h3‘, {‘class‘:‘course-card-name‘}) 时,就报错了。

但是不要慌,BeautifulSoup已经给出修改意见了,它说如果我们想要获取的是一个单一的内容,可以尝试使用find()方法,修改一下我们的代码,再次运行。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib.request
# 导包
from bs4 import BeautifulSoup

# 创建一个Request对象
req = urllib.request.Request(‘http://www.imooc.com‘)

# 使用Request对象发送请求
response = urllib.request.urlopen(req)

soup = BeautifulSoup(response.read(), "lxml")

# 先获取我们刚才找到的div
course_div = soup.find(‘div‘, {‘class‘:‘clearfix types-content‘})

# 再从我们的div里获取想要的内容
course_names = course_div.find_all(‘h3‘, {‘class‘:‘course-card-name‘})

# 这次还会报错吗?
print(course_names)

结果如我们所料,没有报错,并且输出了如下内容:

[<h3 class="course-card-name">全网最热Python3入门+进阶 更快上手实际开发</h3>, <h3 class="course-card-name">玩转数据结构 从入门到进阶</h3>, <h3 class="course-card-name">Java企业级电商项目架 构演进之路  Tomcat集群与Redis分布式</h3>, <h3 class="course-card-name">React Native技术精讲与高质量上线APP开发</h3>, <h3 class="course-card-name"> Vue2.5开发去哪儿网App 从零基础入门到实战项目</h3>]

soup.find() 这个方法,唯一和我们find_all不同的点在于,他们返回的对象不同。find_all返回的是一个bs4.element.ResultSet列表对象。而find返回的是bs4.element.Tag。而find_all返回的列表中,包含的就是一个个的bs4.element.Tag对象。bs4.element.Tag对象,就具有了find或者是find_all的方法,以便我们不断的缩小范围,最终获取我们想要的结果。

你可能认为我们本章到此结束了,并没有结束。因为我们的目的还没达到,我上面说过了,一个好的爬虫就是除了我们想要的内容以外,别的什么都不要有。那我们输出的结果里,显然还包含了 <h3 class="course-card-name"> 这些东西,那怎么样把它过滤掉呢?

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib.request
# 导包
from bs4 import BeautifulSoup

# 创建一个Request对象
req = urllib.request.Request(‘http://www.imooc.com‘)

# 使用Request对象发送请求
response = urllib.request.urlopen(req)

soup = BeautifulSoup(response.read(), "lxml")

# 先获取我们刚才找到的div
course_div = soup.find(‘div‘, {‘class‘:‘clearfix types-content‘})

# 再从我们的div里获取想要的内容
course_names = course_div.find_all(‘h3‘, {‘class‘:‘course-card-name‘})

for course_name in course_names:
    print(course_name.text)

只需要从我们的ResultSet列表对象中,取出每一个Tag对象,然后调用它的text属性,就能获取到标签中的文本内容了~

时间总是过的很快,大家可以在评论中告诉我,用本节学到的知识做了哪些有意思的事情。大家对本系列课程有任何的建议和疑问,都可以通过下方的留言告诉我,每个人的留言我都会看的。

同时大家也可以加入下面两个Python的交流群:

慕课网Python讨论群①:221828022

也可以加入我建的一个Python交流群:685024920

两个群我都有在里面,大家有任何的问题都可以在里面 @秋名山车神~

学习一下我们 liuyubobobo 老师的口头禅,大家加油~电动叉车

同时也希望大家多多支持 liuyubobobo 老师的实战课,多多强化自己的算法内功,早日成功一个优秀的 攻城狮。

原文地址:https://www.cnblogs.com/xyou/p/9017975.html

时间: 2024-08-06 21:21:01

精通Python爬虫-03-狩猎大师的相关文章

精通Python爬虫从Scrapy到移动应用(文末福利)

我能够听到人们的尖叫声:"Appery.io是什么,一个手机应用的专用平台,它和Scrapy有什么关系?"那么,眼见为实吧.你可能还会对几年前在Excel电子表格上给某个人(朋友.管理者或者客户)展示数据时的场景印象深刻.不过现如今,除非你的听众都十分老练,否则他们的期望很可能会有所不同.在接下来的几页里,你将看到一个简单的手机应用,这是一个只需几次单击就能够创建出来的最小可视化产品,其目的是向利益相关者传达抽取所得数据的力量,并回到生态系统中,以源网站网络流量的形式展示它能够带来的价

分享《精通Python爬虫框架Scrapy》中文PDF+英文PDF+源代码

下载:https://pan.baidu.com/s/13tFIFOhDM8PG9pFUuA8M2g 更多分享资料:https://www.cnblogs.com/javapythonstudy/ <精通Python爬虫框架Scrapy>中文PDF+英文PDF+源代码 中文版PDF,364页,带目录和书签,文字可以复制粘贴,彩色配图:英文版PDF,270页,带目录和书签,文字可以复制粘贴,彩色配图:中英文两版对比学习.配套源代码. 其中,中文版如图: 原文地址:https://www.cnbl

分享《精通Python爬虫框架Scrapy》+PDF+源码+迪米特里奥斯+李斌

下载:https://pan.baidu.com/s/1-ruuQebCnyLVt5L8RATT-g 更多资料:http://blog.51cto.com/14087171 <精通Python爬虫框架Scrapy>中文PDF+英文PDF+源代码 中文版PDF,364页,带目录和书签,文字可以复制粘贴,彩色配图:英文版PDF,270页,带目录和书签,文字可以复制粘贴,彩色配图:中英文两版对比学习.配套源代码. 其中,中文版如图: 原文地址:http://blog.51cto.com/140871

Learning Scrapy:《精通Python爬虫框架Scrapy》Windows环境搭建

之前用爬虫抓点数据的时候基本上就是urllib3+BeautifulSoup4,后来又加入requests,大部分情况就够用了.但是最近心血来潮想学一下Scrapy,于是找了本书——<精通Python爬虫框架Scrapy>.内容算是比较可以的,但是按书中附录搭建环境着实折腾了一点时间,于是想把碰到的问题总结一下,让大家也少走点弯路. 进入正题之前,有几点要说明一下: 安装这个环境有什么用?这个环境就是一个服务器,有需要你抓的网站,不会因现实中的网站改版而造成代码失效,书中测试代码的网站基本上都

python爬虫19 | 遇到需要的登录的网站怎么办?用这3招轻松搞定!

你好 由于你是游客 无法查看本文 请你登录再进 谢谢合作 当你在爬某些网站的时候 需要你登录才可以获取数据 咋整? 莫慌 小帅b把这几招传授给你 让你以后从容应对 那么 接下来就是 学习 python 的正确姿势 登录的常见方法无非是这两种 1.让你输入帐号和密码登录 2.让你输入帐号密码+验证码登录 今天 小帅b先跟你说说第一种 需要验证码的咱们下一篇再讲 第一招 Cookie大法 你平常在上某个不为人知的网站的时候 是不是发现你只要登录一次 就可以一直看到你想要的内容 过了一阵子才需要再次登

Python爬虫连载1-urllib.request和chardet包使用方式

一.参考资料 1.<Python网络数据采集>图灵工业出版社 2.<精通Python爬虫框架Scrapy>人民邮电出版社 3.[Scrapy官方教程](http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html) 4.[Python3网络爬虫](http://blog.csdn.net/c406495762/article/details/72858983 二.前提知识 url.http协议.web前端:html\

python爬虫算一下demo大师网站的总创收

用python爬虫算一下demo大师网站的总创收...... #!/usr/bin/env python #coding:utf-8 import requests import json from bs4 import BeautifulSoup def demodashi(url):     response = requests.get(url)     html = response.text     html = json.loads(html)     totalPage = htm

python爬虫从入门到精通-系列教程

开始爬虫之旅 引言 我经常会看到有人在知乎上提问如何入门 Python 爬虫?.Python 爬虫进阶?.利用爬虫技术能做到哪些很酷很有趣很有用的事情?等这一些问题,我写这一系列的文章的目的就是把我的经验告诉大家. 什么是爬虫? 引用自维基百科 网络蜘蛛(Web spider)也叫网络爬虫(Web crawler),蚂蚁(ant),自动检索工具(automatic indexer),或者(在FOAF软件概念中)网络疾走(WEB scutter),是一种“自动化浏览网络”的程序,或者说是一种网络机

Python爬虫入门教程:博客园首页推荐博客排行的秘密

1. 前言 虽然博客园注册已经有五年多了,但是最近才正式开始在这里写博客.(进了博客园才知道这里面个个都是人才,说话又好听,超喜欢这里...)但是由于写的内容都是软件测试相关,热度一直不是很高.看到首页的推荐博客排行时,心里痒痒的,想想看看这些大佬究竟是写了什么文章这么受欢迎,可以被推荐.所以用Python抓取了这100位推荐博客,简单分析了每个博客的文章分类,阅读排行榜,评论排行榜及推荐排行榜,最后统计汇总并生成词云.正好这也算是一篇非常好的Python爬虫入门教程了. 2. 环境准备 2.1