Python爬虫入门

这学期暑假的时候,打开了Learning mall下载下学期的课件,但是却发现LM并没有批量下载功能,最后只能通过一个一个点击来下载。无疑这是一个体验非常不好的过程。所以想写一个爬虫来下载learning mall的课件和资料。
遇到的问题是learning mall是需要登陆才能下载的,登陆无疑是爬虫操作中的一个较难解决的问题。这篇文章会通过爬豆瓣图片的过程和爬learning mall来讲解如何使用Python爬虫解决生活实际问题。

需要准备的工具有: Pycharm, Chrome(安装插件XPath helper)
豆瓣爬的图片😏


抓取豆瓣图片

爬虫过程分为四步

  1. 找到数据
  2. 发送地址请求
  3. 数据解析
  4. 数据保存

目前爬的这个豆瓣页面不需要登陆,但是需要翻页,后面会尝试爬learningmall的课件,那个需要虚拟登陆,但是应该不需要翻页。我们在爬的过程中一定要注意是适度,要是爬的过分可能会导致别人的网页崩溃,就直接进局子了。


找到数据

  • 第一步是先要找到数据,请求URL地址。
  • 第二步是随机大概我们要爬取的一个文件,通过开发者模式打开之后,找到header底下的User-Agent
  • 我们要通过User-Agent来伪装我们的访问,防止被直接Forbidden 403反爬。

以我的电脑为例:

1
2
url = f'https://movie.douban.com/celebrity/1016673/photos/?type=C&start=0&sortby=like&size=a&subtype=a'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'}

发送地址请求

  • 声明变量response,利用requests库的get提取页面的内容并保存在response中。
  • 声明html_data,把response转换成text格式储存进去。
  • 可以通过print来看一下我们保存的内容是否包含了我们想要抓去的内容。

html_data需要我们用正则表达式来表达:

1
2
3
response = requests.get(url=url, headers=headers)  # 把请求伪装成一般的浏览器
html_data = response.text
print(html_data) # 正则

数据解析

XPath helper的用法:

  1. 打开Chrome 安装XPath helper
  2. 打开开发者模式,通过分析html标签,找到我们需要的位置
  3. //表示定位标签,/表示前面标签的下级标签,定位到具体元素的时候用@

我们获得html_data需要定位哪些内容是我们需要爬取的内容,这是就需要用到XPath helper。

  • 安装parsel库,通过这个库转化html_data的数据类型。
  • 用XPath定位分析html标签,找到我们需要的内容的具体url位置。
  • 把这些具体的二级页面的url储存在href_list里。
  • 对于href_list中的二级页面,我们利用分析一级页面的方法再次分析一次,找到要下载的资源具体的URL链接放入img_list

这时候我们已经可以打印出来我们需要的图片具体的url了。

1
2
3
4
5
6
7
8
9
10
11
12
13
selector = parsel.Selector(html_data)  # 转换数据类型
href_list = selector.xpath('//div[@class="cover"]/a/@href').getall()
print(href_list)

for href in href_list:
# 发送图片链接的请求
print(f'当前图片页面地址:', href)
response_2 = requests.get(url=href, headers=headers).text

# 第二次数据解析 解析图片的url地址
selector_2 = parsel.Selector(response_2)
img_list = selector_2.xpath('//div/a[@class="mainphoto"]/img/@src').getall()
print(img_list)

数据保存

既然所以我们需要的内容都已经保存在img_list里了,因为我们这次下载的是图片,所以就最后的结果放在img文件夹里。

  • 用for循环遍历img_list里的每一个元素。
  • 为了不让程序爬的太快被封,我们加上一段sleep,减缓一下爬取的速度。
  • 通过split分割并用最后一段命名文件名。
  • 保存文件至img文件夹。
1
2
3
4
5
6
7
8
for img in img_list:
img_data = requests.get(url=img, headers=headers).content # 这里的数据是二进制 所以用content

time.sleep(1) # 延时1秒 刚开始是5秒 但是速度太慢了
file_name = img.split('/')[-1] # 准备文件名 通过 / 分割 把分割出来的最后一部分作为文件名
with open('img/' + file_name, mode='wb') as f:
f.write(img_data)
print('保存成功:', file_name)

实现翻页

但是这还没有结束,因为这样的爬虫只能爬到第一页的图片,而我们想要他爬到的所有的图片,所以我们需要添加上翻页的功能。

所以估计page1的url就是把30改为0,事实也确实如此,所以我们在整个程序的开头套上一个page作为for循环。爬取的内容一共只有26页,所以我们设置边缘也就是0-750。

1
2
3
4
page_num = 0
for page in range(0, 751, 30): # 每30翻一页 一共750页
page_num += 1
print(f'----------正在爬取第{page_num}页----------')

豆瓣爬虫总结

这样我们就实现了完整的豆瓣爬图片的代码:

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
32
33
34
35
36
37
38
39
40
41
42
43
import time  # 延时用的 爬的太快了容易被发现 把别人网站爬塌了就进局子了

import requests # 第三方模块 terminal: pip install requests
import parsel # 第三方模块 terminal: pip install parsel

page_num = 0
for page in range(0, 751, 30): # 每30翻一页 一共750页
page_num += 1
print(f'----------正在爬取第{page_num}页----------')

# 1. 找到数据 请求url地址
url = f'https://movie.douban.com/celebrity/1016673/photos/?type=C&start={page}&sortby=like&size=a&subtype=a'
# 随便找到一个图片 开发者模式打开之后找到`header`下的`User-Agent`
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'}

# 2. 发送地址请求
response = requests.get(url=url, headers=headers) # 把请求伪装成一般的浏览器
html_data = response.text
# print(html_data) # 正则

# 3. 数据解析
selector = parsel.Selector(html_data) # 转换数据类型
href_list = selector.xpath('//div[@class="cover"]/a/@href').getall()
# print(href_list)

for href in href_list:
# 发送图片链接的请求
print(f'当前图片页面地址:', href)
response_2 = requests.get(url=href, headers=headers).text

# 第二次数据解析 解析图片的url地址
selector_2 = parsel.Selector(response_2)
img_list = selector_2.xpath('//div/a[@class="mainphoto"]/img/@src').getall()
# print(img_list)
for img in img_list:
img_data = requests.get(url=img, headers=headers).content # 这里的数据是二进制 所以用content

# 4. 数据保存
time.sleep(1) # 延时1秒 刚开始是5秒 但是速度太慢了
file_name = img.split('/')[-1] # 准备文件名 通过 / 分割 把分割出来的最后一部分作为文件名
with open('img/' + file_name, mode='wb') as f:
f.write(img_data)
print('保存成功:', file_name)

下面将会介绍如何爬取learningmall中的课件和资料。


Learning Mall 爬虫

To be continued…


References

  1. Python爬虫教程入门教程:从零带你采集某度约会吧上全部小姐姐高清图片,爱了嘛?
作者

Felix Chen

发布于

2021-09-12

更新于

2021-09-12

许可协议

评论