基于爬虫技术的豆瓣读书信息采集

基于爬虫技术的豆瓣读书信息采集

1. 实验目标

爬取豆瓣读书中排名前250本书的信息。

2. 实验主要使用的 𝑃𝑦𝑡ℎ𝑜𝑛Python 库

名称版本简介
𝑅𝑒𝑞𝑢𝑒𝑠𝑡𝑠Requests2.23.02.23.0爬虫网络请求

3. 实验适用的对象

  • 本课程假设您已经学习了 𝑃𝑦𝑡ℎ𝑜𝑛Python 基础,具备机器学习基础
  • 学习对象:本科学生、研究生、人工智能、算法相关研究者、开发者
  • 大数据分析与人工智能

4. 实验步骤

步骤1 安装并引入必要的库

代码示例:

# 安装第三方库
pip install requests==2.23.0
pip install bs4==0.0.1
# 加载第三方库
import requests
from bs4 import BeautifulSoup

步骤2 解析需要爬取的数据

在本次实验中,我们将来学习如何通过爬虫获取豆瓣读书网的前250排名的书籍。

书的名字,作者和出版社信息,豆瓣评分和一句话简介。我们有了目标信息,就需要找到信息所在的页面源码,然后通过解析源码来获取到信息数据。那么,我们怎样获得页面 HTML 源代码呢?翻阅兵书,我们知道可以使用requests之计。代码实现如下 :

代码示例:

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'}
resp = requests.get('https://book.douban.com/top250?start=0', headers=headers)
resp.text

可以看到书名信息包含在class=‘pl2’ div里面的a标签内,是a标签的title属性。发现目标位置后,就简单多了。我们利用BeautifulSoup来获得一个对象,按找标准的缩进显示的html代码:

代码示例:

 soup = BeautifulSoup(resp.text, 'lxml')

步骤3 开始爬取

3.1 获得书名

find() vs find_all()

现在我们要用到BeautifulSoup的find_all()选择器,因为我们这一页有很多书,而每一本书的信息都包含在class=pl2的div标签内,我们使用find_all()就可以直接得到本页所有书的书名了。我们用find()方法和find_all()方法来做一个比较

代码示例:

# find_all()方法,
# 注意class是Python关键词,后面要加下划线_:
alldiv = soup.find_all('div', class_='pl2')
for a in alldiv:names = a.find('a')['title']print('find_all():', names)
# find()方法:
alldiv2 = soup.find('div', class_='pl2')
names2 = alldiv2.find('a')['title']
print('find():', names2 )

我们通过结果就可以看到两者之间的差距了,前者输出了一页的数据,而后者只输出了第一条数据。所以包括后面的信息,由于每一天数据所在标签是一样的,我们都是用find_all()方法。

上面的代码写的优雅点,就是这样实现,注意结果是一个 list:

代码示例:

# 书名, 注意是L小写,不是阿拉伯数字1
alldiv = soup.find_all('div', class_='pl2')
names = [a.find('a')['title'] for a in alldiv]
print(names)
3.2 获取作者信息

这样书名数据我们就得到了,接下来是作者信息。方法和获取书名方法一样:

代码示例:

# 作者,由于信息在一个p标签内部,
# 我们获取到标签直接get_text()方法获得文本内容
allp = soup.find_all('p', class_='pl')
authors = [p.get_text() for p in allp]
3.3 获取其他信息

后面的评分内容和简介内容也是一样获得,只是标签不同,但是方法一样,具体也不需要多余赘述。直接看实现代码:

代码示例:

# 评分
starspan = soup.find_all('span', class_='rating_nums')
scores = [s.get_text() for s in starspan]
# 简介
sumspan = soup.find_all('span', class_='inq')
sums = [i.get_text() for i in sumspan]
3.4 整理数据

程序运行成功,我们就获得了4个list,分别是书名,作者,评分和简介内容。我们要把他们放在一起,打印出来,就是一页的数据信息了。 这里我们使用zip()函数,zip()函数在运算时,会以一个或多个序列做为参数,返回一个元组的列表。同时将这些序列中并排的元素配对。

代码示例:

for name, author, score, sum in zip(names, authors, scores, sums):name = '书名:' + str(name) + '\n'author = '作者:' + str(author) + '\n'score = '评分:' + str(score) + '\n'sum = '简介:' + str(sum) + '\n'data = name + author + score + sum

我们使用换行符’\n‘给数据信息一点整齐的样式。我们可以查看到打印的结果,并没有所有数据黏在一起,显得丑陋。 获得信息后,就是保存数据了。保存数据也很简单,Python的文件读写操作就可以实现。代码如下:

代码示例:

# 文件名
filename = '豆瓣图书Top250.txt'
# 保存文件操作
with open(filename, 'w', encoding='utf-8') as f:# 保存数据f.writelines(data + '=======================' + '\n')
print('保存成功')
3.5 爬取全部数据

但是,我们要的是 250 条数据,而不是一页的十几条数据,那么要怎么获得到所有的数据呢。我们可以检查页面的信息,可以看到页面一共 10 页,第一页的URL是https://book.douban.com/top250?start=0。 而最后一页的 URL 是https://book.douban.com/top250?start=225 我们接着多看几页,第二页是https://book.douban.com/top250?start=25 第三页是https://book.douban.com/top250?start=50。

规律已经很清晰了,我们的页面的页数信息是最后的start=后面的数字。而且数字从0开始到225,每一页数字加 25.这就很简单了,我们以https://book.douban.com/top250?start= 为基层URL,每一页在后面加页面的页数数字。就可以得到所有的页面 url 了。再以for循环迭代每一个 url,使用上面获取数据的方法,获得所有的数据信息。

获取所有页面URL的代码如下:

代码示例:

base_url = 'https://book.douban.com/top250?start='
urllist = []
# 从0到225,间隔25的数组
for page in range(0, 250, 25):allurl = base_url + str(page)urllist.append(allurl)

我们把它保存在list里面,好用作循环迭代。

步骤4 完整流程

那么,所有的功能都实现了。现在,我们只要将所有的代码组合起来,就可以实现我们需要的所有功能了。 上代码:

代码示例:

# 发出请求获得HTML源码的函数
def get_html(url):# 伪装成浏览器访问headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}resp = requests.get(url, headers=headers).textreturn resp

代码示例:

# 解析页面,获得数据信息
def html_parse():# 调用函数,for循环迭代出所有页面for url in all_page():# BeautifulSoup的解析soup = BeautifulSoup(get_html(url), 'lxml')# 书名alldiv = soup.find_all('div', class_='pl2')names = [a.find('a')['title'] for a in alldiv]# 作者allp = soup.find_all('p', class_='pl')authors = [p.get_text() for p in allp]# 评分starspan = soup.find_all('span', class_='rating_nums')scores = [s.get_text() for s in starspan]# 简介sumspan = soup.find_all('span', class_='inq')sums = [i.get_text() for i in sumspan]for name, author, score, sum in zip(names, authors, scores, sums):name = '书名:' + str(name) + '\n'author = '作者:' + str(author) + '\n'score = '评分:' + str(score) + '\n'sum = '简介:' + str(sum) + '\n'data = name + author + score + sum# 保存数据f.writelines(data + '=======================' + '\n')

代码示例:

# 获得所有页面的函数
def all_page():base_url = 'https://book.douban.com/top250?start='urllist = []# 从0到225,间隔25的数组for page in range(0, 250, 25):allurl = base_url + str(page)urllist.append(allurl)return  urllist

代码示例:

# 文件名
filename = '豆瓣图书Top250.txt'
# 保存文件操作
f = open(filename, 'w', encoding='utf-8')
# 调用函数
html_parse()
f.close()
print('保存成功。')
保存成功。

接下来,我们读取刚才爬取下来的文本信息,并打印它。

代码示例:

file_object = open('豆瓣图书Top250.txt') 
lines=file_object.readlines()
lines


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部