Python爬虫简单测试

前提:需要有python和pip环境

写在前言处:需要了解前端的HTML标记和CSS样式,了解python的基本用法

爬虫

首先了解一下爬虫是什么,还有什么注意事项。

爬虫(Web crawler)是一种自动化程序或脚本,用于浏览互联网并自动提取网页内容的工具。它也被称为网络爬虫、网络蜘蛛或网络机器人。

爬虫通过发送HTTP请求访问指定的网页,并从返回的内容中提取有用的信息,例如文本、图片、链接等。它们通常用于数据采集、搜索引擎索引、数据分析、监测网站变化等任务。

爬虫的工作原理通常是:

  1. 指定一个初始URL作为爬取的起点。
  2. 发送HTTP请求获取网页内容。
  3. 解析HTML内容,提取感兴趣的数据,例如链接、文本等。
  4. 如果有新的链接,将其添加到待爬取的URL队列中。
  5. 重复执行步骤2-4,直到满足终止条件(例如爬取的页面数量达到设定值或达到指定深度)。

爬虫可以针对特定的网站进行定向爬取,也可以通过搜索引擎的爬虫来广泛地爬取整个互联网。

注意事项
在爬取过程中,爬虫需要遵守网站的爬取规则道德准则,以避免对网站造成过大的负担或侵犯隐私等问题。

准备工作

安装requests和bs4库

分别在powershell里面执行

1
2
pip install requests
pip install bs4

在Python中,BeautifulSoup(通常简称为bs4)是一个用于解析HTML和XML文档的库。

BeautifulSoup的主要作用如下:

  1. 解析HTML和XML文档:BeautifulSoup可以将HTML或XML文档解析为Python对象,使得我们可以方便地提取其中的数据。
  2. 树形结构遍历:BeautifulSoup将解析的文档构建为树形结构,通过遍历这个结构,我们可以轻松地定位和访问文档中的各个元素。
  3. 数据提取:通过BeautifulSoup提供的一系列方法,我们可以根据标签、类名、属性等条件来提取文档中的数据。例如,我们可以提取所有的链接、图片、段落等。
  4. 数据清洗:BeautifulSoup还可以清洗和格式化提取到的数据。它提供了一些方法来去除HTML标签、删除多余的空白字符等,使得提取到的数据更加干净和易于处理。
  5. 弥补HTML解析器的不足:BeautifulSoup可以与不同的HTML解析器(如Python内置的html.parser、lxml等)配合使用,以弥补解析器在处理不规范或复杂HTML时的不足之处。

一个简单的小Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import requests
from bs4 import BeautifulSoup

def web_crawler(url):
# 发起HTTP GET请求
response = requests.get(url)

# 检查响应状态码
if response.status_code == 200:
# 使用BeautifulSoup解析HTML内容
soup = BeautifulSoup(response.text, "html.parser")

# 获取所有的<a>标签
links = soup.find_all("a")

# 遍历每个链接,并打印标题和URL
for link in links:
title = link.text
href = link.get("href")
print(f"Title: {title}\nURL: {href}\n")
else:
print("Failed to fetch the webpage")

# 指定要爬取的网页URL
url = "https://sanxiaoxing.github.io/"

# 调用爬虫函数
web_crawler(url)

web_crawler函数内部,我们首先发起GET请求,并检查响应状态码。如果响应状态码为200,表示请求成功,我们使用BeautifulSoup解析HTML内容。

接下来,我们使用find_all方法获取网页中所有的<a>标签,并遍历每个链接。我们使用text属性获取链接的文本内容,使用get方法获取链接的URL,并打印标题和URL。

最后,我们在主程序中指定要爬取的网页URL,并调用web_crawler函数来执行爬取操作。


除此之外,有的网站会限制python爬虫进行数据的爬取,这时我们可以使用

1
2
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0'}

进行web的伪装。

提示:user-Agent可以使用web浏览器F12的开发者选项中的网络,进行刷新,随便点击一个即可看到user-Agent的一个内容

把鼠标移动到我上面试试

继续爬取豆瓣电影

了解以上的内容,就可以简单爬取一下豆瓣的电影了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/top250'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

movies = soup.find_all('div', class_='info') # 查找所有属性
for movie in movies:
title = movie.find('span', class_='title').text
rating = movie.find('span', class_='rating_num').text
print(f'电影名字: {title}\t评分: {rating}')

根据上面的代码,不难发现只有第一页的内容,而我们需要前250的内容

豆瓣排名前250名的总排名

那么,我们需要使用一个循环处理每一个页面range(0,250,25)。标识0到250,每次增加25,以便处理页面。

https://movie.douban.com/top250?start=0&filter=在这个连接里面不难看出start是0,翻到下一页就是25,可以得出所需要增加的为25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}

for page in range(0, 250, 25):
url = f'https://movie.douban.com/top250?start={page}'
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

movies = soup.find_all('div', class_='info')
for movie in movies:
title = movie.find('span', class_='title').text
rating = movie.find('span', class_='rating_num').text
print(f'电影名字: {title}\t评分: {rating}')

豆瓣排名前250标号排序

上面的爬取数据只会有名字还有评分,没有排名,接下来我们继续加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}

for page in range(0, 250, 25):
url = f'https://movie.douban.com/top250?start={page}'
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

movies = soup.find_all('div', class_='info')
for idx, movie in enumerate(movies, start=page+1):
title = movie.find('span', class_='title').text
rating = movie.find('span', class_='rating_num').text
print(f'排名: {idx}\t电影名字: {title}\t评分: {rating}')

在更新后的代码中,我们使用了enumerate()函数来获得电影的排名。enumerate()函数会返回一个可迭代对象,同时提供索引和对应的元素。通过设置start=page+1,我们将排名的起始值设置为当前页面的起始值。

那么,还是不满足在控制台输出结果,想在excel表格里面展示,接下来 Show Time

将其数据导入到excel表格里面

要将数据导入excel中,需要使用第三方库openpyxl

1
pip install openpyxl

以下是更新后的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}

# 创建一个新的Excel工作簿
wb = Workbook()
# 获取默认的工作表
ws = wb.active

for page in range(0, 250, 25):
url = f'https://movie.douban.com/top250?start={page}'
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

movies = soup.find_all('div', class_='info')
for idx, movie in enumerate(movies, start=page+1):
title = movie.find('span', class_='title').text
rating = movie.find('span', class_='rating_num').text
ws.cell(row=idx, column=1, value=idx) # 写入排名
ws.cell(row=idx, column=2, value=title) # 写入电影名字
ws.cell(row=idx, column=3, value=rating) # 写入评分

# 保存Excel文件
wb.save('douban_top250.xlsx')

运行完,桌面上就会有一个douban_top250.xlsx文件,就可以看到

但是

还不是最完美的,他没有第一行作为提示

继续改进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'}

# 创建一个新的Excel工作簿
wb = Workbook()
# 获取默认的工作表
ws = wb.active

# 添加列标题
ws['A1'] = '排名'
ws['B1'] = '电影名字'
ws['C1'] = '评分'

for page in range(0, 250, 25):
url = f'https://movie.douban.com/top250?start={page}'
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

movies = soup.find_all('div', class_='info')
for idx, movie in enumerate(movies, start=page+2):
title = movie.find('span', class_='title').text
rating = movie.find('span', class_='rating_num').text
ws.cell(row=idx, column=1, value=idx-1) # 写入排名
ws.cell(row=idx, column=2, value=title) # 写入电影名字
ws.cell(row=idx, column=3, value=rating) # 写入评分

# 保存Excel文件
wb.save('douban_top250.xlsx')

使用ws['A1'] = '排名'将排名列标题写入A1单元格,使用ws['B1'] = '电影名字'将电影名字列标题写入B1单元格,使用ws['C1'] = '评分'将评分列标题写入C1单元格。

同时,我们将循环中写入数据的起始行从page+1修改为page+2,以便为列标题腾出第一行。

目前就是非常完美了