URL查询参数
在文章《爬虫-豆瓣读书排行榜》中,我们只是获取了第一页的25条数据,剩余的9页数据如何爬取呢?
操作步骤
- 点击点击练习素材中的 URL,此时浏览器会在新标签页为你打开豆瓣读书 Top 250 页面,并加载榜单中前 25 本图书信息;
- 滚动到页面最下方,在 页码导航区域 点击页码 2,此时页面会刷新出后 25 本图书信息;
- 滚动到页面最下方,在 页码导航区域 点击页码 3,此时页面会再次刷新后 25 本图书;
- 通过点击页码 1 回到第一页。
将上述操作得到的 URL 按页码顺序排列好,你会得到如下内容:
# 点击页码 1 后 URL
https://book.douban.com/top250?start=0
# 点击页码 2 后 URL
https://book.douban.com/top250?start=25
# 点击页码 3 后 URL
https://book.douban.com/top250?start=50
可以发现,这些 URL 相比于豆瓣读书 Top 250 首页 URL https://book.douban.com/top250,后面多了串小尾巴 ?start=xx,并且随着页码的增加,小尾巴中数字部分也在增加。看起来这串小尾巴的值决定了页面中呈现的内容。
这部分以 ?
开头的内容也是 URL 重要组成部分之一,被称为 查询参数,也叫 查询字符串。
查询参数 用于 过滤、组织、跟踪 网站上的信息,格式上以字符 ?
开始,包含若干个由 key=value
形式 键值对 构成的参数。若 URL 携带多个查询参数,则参数与参数之间需要用 &
相连,写成 ?key1=value1&key2=value2&...
形式。
import requests
from bs4 import BeautifulSoup
# 豆瓣读书 Top 250 首页 URL
base_url = 'https://book.douban.com/top250/'
# 定制消息头
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
}
# 定制查询参数
params = {
'start': 0
}
# 发送带消息头、查询参数的请求
res = requests.get(base_url, headers=headers, params=params)
print(res)
# 输出:<Response [200]>
代码中我们创建了字典params,并为start键赋值为0,接着我们通过参数params吧定制的查询参数传递给get()方法,大家也可修改start的值可以来验证下。
下面是完整代码
import time
# 将获取一页图书数据代码封装成函数 get_one_page_data()
def get_one_page_data(page):
# 豆瓣读书 Top 250 首页 URL
base_url = 'https://book.douban.com/top250'
# 定制消息头
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
}
# 根据传入参数定制查询参数
params = {
'start': 25 * (page - 1)
}
# 发送带消息头和查询参数的请求
res = requests.get(base_url, headers=headers, params=params)
# 解析成 BeautifulSoup 对象
soup = BeautifulSoup(res.text, 'html.parser')
# 提取出书名、作者、出版社信息并按行打印
book_name_tags = soup.select('div.pl2 a')
book_info_tags = soup.select('p.pl')
for i in range(len(book_name_tags)):
book_name = book_name_tags[i]['title']
info = book_info_tags[i].text
info_list = info.split('/')
author = info_list[0]
publisher = info_list[-3]
print(book_name, author, publisher)
# 循环 10 次,分别获取第 1~10 页数据
for i in range(1, 11):
get_one_page_data(i)
time.sleep(1)
代码中我们封装了一个get_one_page_data()方法,参数是页数page,再结合for循环,实现了爬取了所有的数据。
在此使用了time.sleep(1)来暂停1秒的目的是为了网站反爬虫,把我们给封了。