『Python爬虫』极简入门

本文简介

点赞 + 收藏 + 关注 = 学会了

声明:请勿使用爬虫技术获取公民隐私数据、+-数据以及企业或个人不允许你获取的数据。

本文介绍如何使用 Python 写一只简单的爬虫,作为入门篇,这个程序不会很复杂,但至少可以讲明爬虫是个什么东西。

写一个爬虫程序其实很简单,从整体来看只需3步:

  1. 发起网络请求,获取网页内容。
  2. 解析网页的内容。
  3. 储存数据,或者拿来做数据分析。

但第三步其实已经不属于“爬”这个动作了,所以本文只介绍前2步。至于第三步存储数据,之后会写几篇文章讲讲 Python 如何操作数据库,之后也会介绍 Python 热门的数据分析工具(先画个饼)。

动手操作

十个教爬虫,九个爬豆瓣。注意,本文只是拿豆瓣来举例,你可不要真的24小时一直在爬它呀。

发起网络请求

Python 中要发起网络请求,可以使用 requests

如果还没安装 requests 可以用以下命令安装

pip install requests

然后引入使用

import requests

我要获取豆瓣电影Top250的数据,电影Top250的页面地址是 https://movie.douban.com/top250。可以用 get 请求。

res = requests.get("https://movie.douban.com/top250")
print(res)

上面这段代码的意思是通过 requests.get 发起 get 请求,并把结果输出看看。

01.png

看到输出结果的状态码是 418,表示豆瓣的服务器不想理你。

出现这种情况的原因是豆瓣只想服务用浏览器访问的用户,你通过写代码的方式来访问它就不想鸟你了。

于是我们可以通过请求头模拟自己是浏览器。打开浏览器,按F12,切换到Network,然后刷新一下页面。之后随便点一个请求,把它的 User-Agent 的值复制下来。

02.png

在使用 requests 发起请求时在 headers 里把 User-Agent 的值带上。

# 获取数据
headers = {"User-Agent": "你的 User-Agent"}
res = requests.get("https://movie.douban.com/top250", headers=headers)

print(res)

03.png

此时状态码返回 200 证明成功了。

除了 200 可能还有其他状态码是表示成功的,如果要逐一判断是比较麻烦的。requests 的返回值里提供了一个 .ok 的属性帮助我们快速判断响应内容是否获取成功。

# 省略前面的代码...

print(res.ok)

如果 res.ok 返回 Treu 就表示响应成功。

然后我们看看返回的内容是什么,可以查看 .text

if (res.ok):
    print(res.text)

04.png

返回的是这个页面的 HTML 内容。到此,我们获取这个页面的数据已经成功了。接下来要做的就是解析这个页面的数据。

解析网页内容

本文介绍一个很简单的解析网页元素的工具,叫 Beautiful Soup 中文名叫“靓汤”,广东人最爱。

在写本文时,Beautiful Soup 已经出到第4版了。

要安装 Beautiful Soup 可以使用下面这条命令。

pip install beautifulsoup4

然后引入使用。我们接回上面的内容

from bs4 import BeautifulSoup
import requests

# 获取数据
headers = {"User-Agent": "你的 User-Agent"}
res = requests.get("https://movie.douban.com/top250", headers=headers).text

print(res)

此时输出的内容是

05.png

看红色箭头指向的那句就是电影名了。<span class="title">霸王别姬</span>

这个电影名用 span 标签包裹着,而且它的 classtitle

于是我们可以使用 BeautifulSoupfindAll 找到所有符合 classtitlespan 元素。

# 省略部分代码

# 把内容丢给 BeautifulSoup 解析
soup = BeautifulSoup(res, "html.parser")
# 使用 findAll 找到所有 class 为 title 的 span 元素
all_films = soup.findAll("span", attrs={"class": "title"})
print(all_films)

输出的结果如下图所示:

06.png

这样就把本页符合规则的标签都整理出来了。

BeautifulSoup 第一个参数是要解释的内容,第二个参数 html.parser 是告诉 BeautifulSoup 要解析的是 HTML 内容。

接下来我们可以使用 for 循环把这些标签逐个输出,并使用 .string 属性把标签里的字符串提取出来。

for film_name in all_films:
  print(film_name.string)

07.png

问题来了,为什么有些电影名前面有斜杠,有些又没有斜杠?

08.png

打开网页看源码,电影名的别名是用斜杠分隔的,而且它们都符合 <span class="title"> 这个规则。

所以我们在遍历的时候可以将不含斜杠的电影名提取出来。

for film_name in all_films:
    if '/' not in film_name.string:
        print(film_name.string)

09.png

但这电影数量和Top250的数量相差甚远。原因是我们爬取的这页只展示了25条数据。

10.png

如果要爬取250条数据就要先搞清分页时要传什么参数。

点开第2页可以看到url变了。多了个 start=25

11.png

点开第3页发现 start=50 。我们根据这个规则可以写一个遍历方法,将250条数据都拿回来。

具体代码如下:

from bs4 import BeautifulSoup
import requests

# 设置请求头
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"}

# 按规律遍历,请求Top250数据
for start_num in range(0, 250, 25):
    res = requests.get(f"https://movie.douban.com/top250?start={start_num}", headers=headers)
    soup = BeautifulSoup(res.text, "html.parser") # 开始解析html
    all_films = soup.findAll("span", attrs={"class": "title"}) # 获取所有电影名(含html标签)
    for film_name in all_films:
        if '/' not in film_name.string:
            print(film_name.string)

只需十来行代码就把豆瓣Top250的电影名都拿下了。

总结

python 是很擅长写爬虫的,相关的工具也非常多。本文介绍的属于最简单的一种爬虫,主要给各位工友建立学习信心。

之后会介绍更多爬虫相关的工具。


点赞 + 关注 + 收藏 = 学会了

IMG_2952.GIF

posted @ 2024-05-28 12:41  德育处主任  阅读(11)  评论(0编辑  收藏  举报