百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

5分钟轻松学Python4行代码写一个爬虫

toyiye 2024-06-21 12:21 9 浏览 0 评论


编程不是科学,而是一门手艺

Python 具有丰富的解析库和简洁的语法,所以很适合写爬虫。这里的爬虫指的是爬取网页的“虫子”。简而言之,爬虫就是模拟浏览器访问网页,然后获取内容的程序。

爬虫工程师是个很重要的岗位。爬虫每天爬取数以亿计的网页,供搜索引擎使用。爬虫工程师们当然不是通过单击鼠标右键并另存的方式来爬取网页的,而会用爬虫“伪装”成真实用户,去请求各个网站,爬取网页信息。

本文选自《Python基础视频教程》一书,每一小节都给出了视频讲解,配合视频微课带你快速入门Python。



( 正 文 )

1、初识 HTTP :4行代码写一个爬虫

超文本传输协议(HyperText Transfer Protocol,HTTP)是网络中最常见的网络传输协议。常见网站的网址大都以 http 开头或者以 https 开头,https 在 http 基础上做了一层加密的协议。

通常情况下,在浏览器里给服务器发送 http 或 https 请求,服务器拿到请求后会向浏览器返回相应的结果(response),浏览器解析、润色后呈现给用户。

写爬虫没有那么难,下面用 4 行代码写一个爬虫。在 first_spider.py 文件中写入以下代码:

1from urllib import request
2page = request.urlopen('http://www.yuqiaochuang.com/')
3ret = page.read()
4print(ret)


python first_spider.py 运行后,会看到屏幕上打印出了页面的源代码,这短短 4行就是一个爬虫。

从本质上来说,这和打开浏览器、输入网址去访问没有什么区别,只不过后者是借助浏览器获取页面内容,而爬虫则是用原生的 HTTP 获取内容。屏幕上打印的源代码和在 Chrome 浏览器中单击鼠标右键,然后在弹出的快捷菜单中单击“查看网页源代码”是一样的。

在此可以看到,网页的源代码是由很多标签组成的。

尖括号包围的就是一个标签,如<head><body><div>。标签内可以有属性,例如<html lang="zh-CN">,有一个值为"zh-CN"的 lang 属性,表示语言是中文。标签通常是成对出现的,例如,<title>Python 教程 - 雨敲窗个人博客</title>。“Python 教程 - 雨敲窗个人博客”被<title>和</title>包括起来,包括起来的部分被称为标签的内容。


2、正则表达式

前面用 4 行代码写了一个爬虫,运行成功后可以看到爬取的内容。不过,这却是一个大块的内容,如果想提取其中的某些字段该怎么办?

常用的做法就是用正则表达式(Regular Expression)提取。

对初学编程的人来说,很难理解正则表达式是“何方神圣”。其实大家可以把正则表达式当作一个提取器来看,通过制定一些规则,从字符串中提取出想要的内容。

下面先看看正则表达式的几个简单用法。在regular_expression.py 文件中写入以下代码:

1import re # 正则表达式的包
2
3m = re.findall("abc", "aaaaabcccabcc")
4print(m)
5m = re.findall("\d", "abc1ab2c")
6print(m)
7m = re.findall("\d\d\d\d", "123abc1234abc")
8print(m)
9m = re.findall(r"<div>(.*)</div>", "<div>hello</div>")
10print(m)
11m = re.findall(r"<div>(.*)</div>", "<div>hello</div><div>world</div>")
12print(m)
13m = re.findall(r"<div>(.*?)</div>", "<div>hello</div><div>world</div>")
14print(m)


python regular_expression.py 的运行结果如下:

1['abc', 'abc']
2['1', '2']
3['1234']
4['hello']
5['hello</div><div>world']
6['hello', 'world']


首先,需要“import re”,以引用正则表达式模块,这样才能使用正则表达式库中的方法。

之后,上述代码中的 m = re.findall("abc", "aaaaabcccabcc") 从"aaaaabcccabcc"中提取出"abc",返回的 m 是一个列表,里面有两个'abc'。

m = re.findall("\d", "abc1ab2c") 从"abc1ab2c"中提取出单个数字,"\d"表示提取的目标字符是数字,返回的结果是['1', '2'] 。

m = re.findall("\d\d\d\d", "123abc1234abc")提取 4 个连续的数字,返回的结果是['1234']。

m = re.findall(r"<div>(.*)</div>", "<div>hello</div>")从"<div>hello</div>"中提取出<div>和</div>中间的内容,括号括起来就表示提取括号中的内容,“.”表示可以匹配任何字符,“*”表示可以匹配任意多个字符,返回的结果是['hello']。

m = re.findall(r"<div>(.*)</div>", "<div>hello</div><div>world</div>")从"<div> hello</div><div>world</div>" 中 取 div 中 的 内 容 , 返 回 的 结 果 是 ['hello</div> <div>world']。与上一行的提取规则相同,为什么没有单独提取出 hello 和 world 呢?因为正则表达式默认用的是贪婪匹配,所谓贪婪匹配就是能匹配多长就匹配多长。"<div>hello</div><div>world</div>"就从头匹配到了末尾,提取出来一个大长串。

m = re.findall(r"<div>(.*?)</div>", "<div>hello</div><div>world</div>") 在括号中加入一个“?”就表示以非贪婪匹配去提取,即能匹配多短就匹配多短,所以提取出来的结果是['hello', 'world']。

结合前面的几个例子,可以总结出正则表达式中最常用的 findall 方法的用法。第一个参数是定义的提取语法,第二个参数是原始字符串。返回的是一个列表,列表里是符合提取规则的字符串。

关于正则表达式更详细的语法,大家可以借助搜索引擎,搜索“菜鸟教程正则表达式”。


3、爬取静态页面的网站

还 记 得 前 面 写 的 那 个 只 有 4 行 码 的 爬 虫 吗 ?它 爬 取 了 “ http://www. yuqiaochuang.com”整个页面的内容。在学过正则表达式之后,就可以提取想要的内容。

还是以爬取这个博客为例,提取这个博客上文章列表的标题。

在爬取一个网站前,通常要先分析一下这个网站是否是静态页面。静态页面是指,网站的源代码里包含所有可见的内容,也就是所见即所得。常用的做法是,在浏览器中单击鼠标右键,然后在弹出的快捷菜单中选择“显示网页源代码”,推荐使用 Chrome 浏览器。

类似上图中的代码,就是网页的源代码,这里能够看到该博客中文章的标题和网址。

接下来使用正则表达式提取各标题。前面那个只有 4 行代码的爬虫用的是标准库里的urllib 库。推荐使用 requests 库,其具有更强大、更易用的功能。使用 pip 安装,在 PowerShell 命令行窗口中输入以下命令:

1pip install requests


上述代码的前两行先将要使用的库“import”进来,然后调用 requests 库中的 get方法获取页面(page)。之后使用 re.findall 方法提取所有的标题,page.text 即页面的源代码内容。将页面中以“<p><a.*>”开头、“</a></p>”结尾的标题提取出来。

若欲了解更多与 requests 库相关的资料,可以借助搜索引擎,搜索“python requests”查看具体用法。


4、beautifulsoup4

beautifulsoup4 也是一个 Python 的第三方库,提供解析网页的功能。其有些类似于正则表达式,但是比正则表达式的语法更加优雅和便利。

在 PowerShell 命令行窗口中输入以下命令安装 beautifulsoup4:

1pip install beautifulsoup4


还是以“http://www.yuqiaochuang.com”的网页源代码为例,提取这些文章的标题和链接。在 blog_spider_use_bs4.py 文件中写入以下代码:

1from bs4 import BeautifulSoup
2import requests
3page = requests.get('http://www.yuqiaochuang.com/')
4soup = BeautifulSoup(page.text, features="html.parser")
5all_title = soup.find("div", "entry-content").find_all("a")
6for title in all_title:
7 print(title["href"], title.string)


“from bs4 import BeautifulSoup ”将 BeautifulSoup 引 程 序 。

“ soup = BeautifulSoup(page.text, features="html.parser")”声明了一个解析结构 soup。这里解析的是爬取的网页源代码 page.text;features 指定了“html.parser”这个默认的解析器。

在此可以看到,想爬取的标题都在 class 是“entry-content”的 div 块中。“soup.find("div", "entry-content")”用于提取 class 是“entry-content”的 div 块。紧接着调用 find_all,爬取所有标题的标签。find_all 方法返回的是一个列表,这个列表中的元素是符合查找条件的标签。

然后写一个循环,把标题的标签打印下来。通过调用 title["href"]可以获取标签中属性的值—链接。title.string 则是获取标签中的内容。


5、爬取图片

如果网站中仅有枯燥的文字,则很难吸引用户持续观看,所以,好的网站都是图文并茂的。如果想将图片也爬取下来,该怎么办呢?爬虫当然也可以爬取图片,就像在用浏览器访问网站时,可以在图片上单击鼠标右键,然后在弹出的快捷菜单中选择“另存为”选项去下载图片一样。

利用 requests 库也可以抓取图片。还是以爬取“http://www.yuqiaochuang.com”为例,这次爬取网站左上角的图片。在左上角的图片上面单击鼠标右键,接着在弹出的快捷菜单中选择“检查”。

在此可以看到,浏览器下方区域出现了一个工具栏,里面突出显示的部分就是图片地址的网页源代码。

在此可以看到,图片是以“img”标签开头的。这个“img”标签在 class 是“profile”的 div 中,因此可以使用 requests+beautifulsoup4 提取图片的地址。

在 image_spider.py文件中写入以下代码:

1from bs4 import BeautifulSoup
2import requests
3
4page = requests.get('http://www.yuqiaochuang.com/')
5soup = BeautifulSoup(page.text, features="html.parser")
6img = soup.find("div", "profile").find("img")
7print(img["src"])


python image_spider.py 的运行结果如图下。

soup.find("div", "profile").find("img") 直接提取了 img 标签,然后打印 img 标签中的 src 字段,在此可以看到图片地址被提取了出来。但是,你有没有发现这个链接地址似乎少了一些前缀?

没错,少了"http://www.yuqiaochuang.com"。有些网站的图片会省略前缀,在爬取时补上即可。接下来正式爬取图片,在 image_spider.py 文件中写入以下代码:

1from bs4 import BeautifulSoup
2import requests
3
4page = requests.get('http://www.yuqiaochuang.com/')
5soup = BeautifulSoup(page.text, features="html.parser")
6img = soup.find("div", "profile").find("img")
7
8image_url = "http://www.yuqiaochuang.com" + img["src"]
9img_data = requests.get(image_url)
10img_file = "image.png"
11
12f = open(img_file, 'wb')
13f.write(img_data.content)
14f.close()


python image_spider.py 运行后,可以看到当前文件夹下多了一个“image.png”图片文件。

在获取图片地址后,调用 requests 的 get 方法,获取图片的请求数据,然后调用写文件的方法,将图片数据写入到文件中。

前面爬取文字时,调用的是 text 字段,为什么这里变成了 content 字段呢?

这是因为 content 是最原始的数据,二进制的数据流;而 text 则是经过编码的数据。在写文件时,参数也不是'w',而是'wb'。'wb'的意思是,写入的数据是二进制数据流,而不是经过编码的数据。爬取图片和爬取文字的本质,都是根据网页链接发送请求,然后获取内容,只不过图片需要用二进制的形式保存到本地文件中。


—— 完 ——


对编程充满向往和好奇,却不知如何上手吗?

博文视点学院精品课程【每天5分钟:Python基础视频教程(书+课)】带你打开编程世界的大门!

今日仅需39元,你将获得:

  • 300分钟、46节视频讲解
  • 社群答疑,同行交流,互助成长
  • 价值59元的《Python基础视频教程》图书一本

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码