本文以豆瓣首页搜索图书、电影等结果页面为例,使用python的BeautifulSoup解析页面内标题、作者、出版社、评分、简介、缩略图等内容,并转成json格式进行存储。
声明:本文仅作学习python对html解析方法的交流使用,不针对特定网站。
首先我们通过豆瓣首页搜索python,点击书籍的分类,F12查看页面元素。
我们通过CTR+F 查询到页面中搜索的结果都在result-list下的<div class="result">
标签中。
所以下面我们的思路就是循环取出该标签,并提取相应元素。
(在此页面搜索结果展示其实是不全的,还有个显示更多的问题,本文重点在页面解析,获取更多的操作暂不做讨论。)
<div class="result">
<div class="pic">
<a class="nbg" href="https://www.douban.com/link2/?url=https%3A%2F%2Fbook.douban.com%2Fsubject%2F26829016%2F&query=python&cat_id=1001&type=search&pos=0" target="_blank" onclick="moreurl(this,{i: '0', query: 'python', from: 'dou_search_book', sid: 26829016, qcat: '1001'})" title="Python编程" ><img src="https://img9.doubanio.com/view/subject/s/public/s28891775.jpg"></a>
</div>
<div class="content">
<div class="title">
<h3>
<span>[书籍]</span> <a href="https://www.douban.com/link2/?url=https%3A%2F%2Fbook.douban.com%2Fsubject%2F26829016%2F&query=python&cat_id=1001&type=search&pos=0" target="_blank" onclick="moreurl(this,{i: '0', query: 'python', from: 'dou_search_book', sid: 26829016, qcat: '1001'})" >Python编程 </a>
<span class="ic-mark ic-book-mark">可试读</span>
<span class="ic-mark ic-read-mark">有电子版</span>
</h3>
<div class="rating-info">
<span class="allstar45"></span>
<span class="rating_nums">9.1</span>
<span>(3657人评价)</span>
<span class="subject-cast">[美] 埃里克·马瑟斯 / 袁国忠 / 人民邮电出版社 / 2016</span>
</div>
</div>
<p>本书是一本针对所有层次的Python 读者而作的Python 入门书。全书分两部分:第一部分介绍用Python 编程所必须了解的基本概念,包括matplotlib、NumPy 和Pygal 等强大的Py...</p>
</div>
</div>
初步分析后,我们开始代码实操:
先定义一个方法获取当前页面的html代码,然后对每个元素进行解析
import requests
from bs4 import BeautifulSoup
import json
# 通过url获取html数据
def fromUrlToHtml(url,pathName):
# 请求头
headers = {
'User-Agent':'Mozilla/5.0 (Macintoosh; Intel Mac OS X 101_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
}
# 发送请求
res = requests.get(url = url,headers = headers)
status = res.status_code
print(status)
if status == 200:
# print(res.content.decode('utf-8'))
with open('./' + pathName +'.html','w',encoding = 'utf8') as fp:
fp.write(res.content.decode('utf-8'))
# 解析获取的html数据
def fromHtmlToJson(pathName):
# 创建一个 beautifulsoup对象,指定解析器为lxml
fp = open('./' + pathName +'.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
# print(soup)
a = soup.select('.result')
data = []
num = len(a)
for i in range(0,num):
# 将result的内容转成soup对象
soupA = BeautifulSoup(str(a[i]),'lxml')
# 获取详情页url
url = soupA.find(class_="nbg").attrs['href']
# 获取图片地址
picUrl = soupA.find("img").attrs['src']
# 获取标题
title = soupA.find("a").attrs['title']
# 获取评分
ratingNum = soupA.find(class_ = 'rating_nums')
# 获取作者\出版信息等
subject = soupA.find(class_ = 'subject-cast')
# 获取内容简介
summary = soupA.find("p")
# 空值处理
if(None == ratingNum):
ratingNum = "暂无评分"
else:
ratingNum = "豆瓣评分:" + ratingNum.text
if (None == subject):
subject = "暂无信息"
else:
subject = subject.text
if (None == summary):
summary = "暂无简介"
else:
summary = summary.text.replace("\n","")
dict = {"id":str(i+1),"type": "图书", "title": title, "subject": subject, "ratingNum": ratingNum, "url": url,
"picUrl": picUrl, "summary": summary}
data.append(dict)
print("共计" + str(num) + "条,第" +str(i+1)+ "条解析成功")
# print(data)
# 以JSON格式写入数据
with open('./'+ pathName +'.json', 'w', encoding='utf-8') as fp:
json.dump(data, fp, ensure_ascii=False)
print("写入json成功")
if __name__ == '__main__':
url = "https://www.douban.com/search?cat=1001&q=python"
pathName = "bookSearch"
fromUrlToHtml(url,pathName)
fromHtmlToJson(pathName)
运行后控制台打印结果,证明数据解析成功
共计20条,第1条解析成功
共计20条,第2条解析成功
共计20条,第3条解析成功
共计20条,第4条解析成功
共计20条,第5条解析成功
共计20条,第6条解析成功
共计20条,第7条解析成功
共计20条,第8条解析成功
共计20条,第9条解析成功
共计20条,第10条解析成功
共计20条,第11条解析成功
共计20条,第12条解析成功
共计20条,第13条解析成功
共计20条,第14条解析成功
共计20条,第15条解析成功
共计20条,第16条解析成功
共计20条,第17条解析成功
共计20条,第18条解析成功
共计20条,第19条解析成功
共计20条,第20条解析成功
写入json成功
查看数据: