bs4解析入门:爬取当当网30天内热销的书名和价格
目录
一、分析网页:
二、爬取
(一)发起请求+获得网页源码
(二)解析数据
1.实例化
2.通过标签抓取
三、改进
四、错误
(一)不可连用 find_all
(二)字符串与数字不得直接拼接
(三).find返回的结果
五、代码
bs4 是 html 里通过标签名和属性定位数据内容,以达到解析数据的目的
一、分析网页:
本次抓取当当网近一月图书畅销排行榜书名,定位到所需要的用到的标签

这个网页发起 get 请求,返回 text 类型的网页源码

抓取思路:
1.拿到源代码
2.使用 bs4 进行数据解析,拿到想要的结果
二、爬取
(一)发起请求+获得网页源码
本次实例重在体会 BS4 数据解析方法,所以把两步放在一起了
# 指定URL
url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-1'# UA伪装
head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}# 获得响应数据
response = requests.get(url, headers=head).text
(二)解析数据
1.实例化
bs4 是把页面源代码交给 beautifulsoup 处理,生成bs对象(理解为实例化一个 beautifulsoup 类)
soup = BeautifulSoup(response, "html.parser")
print(type(soup))
# 指定 html 解析器,否则Python会有警告,不知道用哪种解析器
2.通过标签抓取
从 bs 对象中查找数据,有find(标签,属性1=值1)和find_all(标签,属性1=值1)两种方法,功能是找第一个标签/所有标签所标记的
观察标签的结构:在
- →
- →→
现在我知道每个
- 标签对应着一本书,里面对应不同信息,如名称价格等,我们需要的书名就放在下的超链接标签中

定位到 ul:
html_1 = soup.find("ul", attrs={'class': "bang_list clearfix bang_list_mode"})定位到 li:
html_2 = html_1.find_all("li")我们需要遍历当下每个 li 标签,然后获得书名
top=1# 遍历网页源码的列表 for i in range(20):# 将li中name类型的div标签赋给book_name_lablebook_name_lable = html_2[i].find("div", class_="name")# a标签中标记的就是书名,利用.text可以拿到标签所标记的内容book_name = book_name_lable.find("a").textprint(str(top)+book_name) #记得 str,+是不能拼接数字和字符串的i += 1top +=1这样我们就能看到第一页的Top20:
1乡土中国(精装版 附赠书签) 2我与地坛(纪念版) 3红星照耀中国 青少版 八年级上册 人民文学出版社 团购电话40010... 4中国古代神话 山海经 希腊神话故事 世界经典神话与传说故事四年级... 5中国民间故事 田螺姑娘 快乐读书吧五年级上册推荐阅读(中小学生课... 6被讨厌的勇气:“自我启发之父”阿德勒的哲学课 岸见一郎 7童年 快乐读书吧六年级上指定阅读 《语文》阅读丛书 人民文学出版... 8朝花夕拾 七年级上 名著阅读课程化丛书 导读版 人民教育出版社 9长安的荔枝 10活着(余华代表作,精装,易烊千玺推荐阅读) 11童年(小学语文“快乐读书吧”・六年级上阅读,高尔基自传体三部... 12朝花夕拾(《语文》推荐阅读丛书)七年级上册推荐阅读 人民文学... 13你也走了很远的路吧(新增2万余字,4篇文章,关于特殊时期成长的... 14红楼梦原著版(上、下册,全两册,全本120回)(团购电话:400-10... 15人教版快乐读书吧阅读课程化丛书 三年级上册套装(稻草人+安徒生... 16红星照耀中国 八年级上 名著阅读课程化丛书 导读版 人民教育出版... 17蛤蟆先生去看心理医生(热销300万册!英国经典心理咨询入门书,知... 18我从未如此眷恋人间:周深“终于开始学会眷恋这人间”史铁生、季... 19小英雄雨来 童年 爱的教育 六年级上册快乐读书吧推荐阅读(中小学... 20中国古代神话 快乐读书吧四年级上册推荐阅读(中小学生课外阅读指...Process finished with exit code 0三、改进
我不想局限于第一页,我想看前5页的Top100畅销书书名:


点击第二页时,最后一个数字发生了变化,所以只要将最后一个数字改为动态的,即可灵活获取想要的数据了
top = 1for p in range(5):response = requests.get(new_url%p, headers=head).textsoup = BeautifulSoup(response, "html.parser") # 指定html解析器,Python会有警告html_1 = soup.find("ul", attrs={'class': "bang_list clearfix bang_list_mode"})html_2 = html_1.find_all("li")for i in range(len(html_2)): # 遍历网页源码的列表book_name_lable = html_2[i].find("div", class_="name")book_name = book_name_lable.find("a").textprint(str(top) + book_name)i += 1top += 1嵌套循环:每页都会发起一个请求获得数据,并实例化一个 BeautifulSoup,找到一页中所有
- 标签
之后,根据- 标签个数进行循环(一页20个
- 标签表示20个书本,每个
- 都要定位到为止才能取到名字并打印输出)
结果成功获取前1-100的书名

为了更详细了解价格与折扣,我又加了一点点细节:
for p in range(5):response = requests.get(new_url % p, headers=head).textsoup = BeautifulSoup(response, "html.parser") # 指定html解析器,Python会有警告html_1 = soup.find("ul", attrs={'class': "bang_list clearfix bang_list_mode"})html_2 = html_1.find_all("li")for i in range(len(html_2)): # 遍历网页源码的列表book_name_lable = html_2[i].find("div", class_="name")book_name = book_name_lable.find("a").textprice_div = html_2[i].find("div", class_="price")price_lable = price_div.find("p")my = price_lable.find("span", attrs={"span", "price_n"}).textsy = price_lable.find("span", attrs={"span", "price_r"}).textdiscount = price_lable.find("span", "price_s").textprint('Top' + str(top) + ':' + book_name + ' 实洋:' + sy + ' 码洋:' + my + ' 折扣:' + discount)i += 1top += 1看起来效果还行

四、错误
(一)不可连用 find_all

这是因为 find_all 得到的是结果集,不唯一,在连续使用 find_all 时会出现这个报错
(二)字符串与数字不得直接拼接
(三).find返回的结果

.find返回的结果是标签,需要再后面加上.text才可得到网页中对应标签标记的内容,如果是想拿到标签的值,用 .get 即可(如图片链接会保存在属性中)
五、代码
import requests from bs4 import BeautifulSoupurl = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-1' new_url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-%d'head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}response = requests.get(url, headers=head).textsoup = BeautifulSoup(response, "html.parser") # 指定html解析器,Python会有警告top = 1 for p in range(5):response = requests.get(new_url % p, headers=head).textsoup = BeautifulSoup(response, "html.parser") # 指定html解析器,Python会有警告html_1 = soup.find("ul", attrs={'class': "bang_list clearfix bang_list_mode"})html_2 = html_1.find_all("li")for i in range(len(html_2)): # 遍历网页源码的列表book_name_lable = html_2[i].find("div", class_="name")book_name = book_name_lable.find("a").textprice_div = html_2[i].find("div", class_="price")price_lable = price_div.find("p")my = price_lable.find("span", attrs={"span", "price_n"}).textsy = price_lable.find("span", attrs={"span", "price_r"}).textdiscount = price_lable.find("span", attrs={"span", "price_s"}).textprint('Top' + str(top) + ':' + book_name + ' 实洋:' + sy + ' 码洋:' + my + ' 折扣:' + discount)i += 1top += 1本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈! - 标签对应着一本书,里面对应不同信息,如名称价格等,我们需要的书名就放在下的超链接标签中
