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会有警告,不知道用哪种解析器

<class 'bs4.BeautifulSoup'>

2.通过标签抓取

        从 bs 对象中查找数据,有find(标签,属性1=值1)find_all(标签,属性1=值1)两种方法,功能是找第一个标签/所有标签所标记的

        观察标签的结构:在<ul class="bang_list clearfix bang_list_mode">→<li class>→<div class="name">→<a href="xxx">

        现在我知道每个<li>标签对应着一本书,里面<div>对应不同信息,如名称价格等,我们需要的书名就放在<div class=“name”>下的超链接标签<a href="xxx">中

定位到 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_lable
    book_name_lable = html_2[i].find("div", class_="name")
    # a标签中标记的就是书名,利用.text可以拿到标签所标记的内容
    book_name = book_name_lable.find("a").text
    print(str(top)+book_name) #记得 str,+是不能拼接数字和字符串的
    i += 1
    top +=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 = 1

for p in range(5):
    response = requests.get(new_url%p, headers=head).text
    soup = 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").text
        print(str(top) + book_name)
        i += 1
        top += 1

        嵌套循环:每页都会发起一个请求获得数据,并实例化一个 BeautifulSoup,找到一页中所有<li> 标签之后,根据<li>标签个数进行循环(一页20个<li>标签表示20个书本,每个<li>都要定位到<a>为止才能取到名字并打印输出)

        结果成功获取前1-100的书名

         为了更详细了解价格与折扣,我又加了一点点细节:

for p in range(5):
    response = requests.get(new_url % p, headers=head).text
    soup = 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").text
        price_div = html_2[i].find("div", class_="price")
        price_lable = price_div.find("p")
        my = price_lable.find("span", attrs={"span", "price_n"}).text
        sy = price_lable.find("span", attrs={"span", "price_r"}).text
        discount = price_lable.find("span", "price_s").text
        print('Top' + str(
            top) + ':' + book_name + '            实洋:' + sy + '          码洋:' + my + '           折扣:' + discount)
        i += 1
        top += 1

        看起来效果还行

四、错误

(一)不可连用 find_all

        这是因为 find_all 得到的是结果集,不唯一,在连续使用 find_all 时会出现这个报错

(二)字符串与数字不得直接拼接

(三).find返回的结果

        .find返回的结果是标签,需要再后面加上.text才可得到网页中对应标签标记的内容,如果是想拿到标签的值,用 .get 即可(如图片链接会保存在属性中)

五、代码

import requests
from bs4 import BeautifulSoup

url = '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).text

soup = BeautifulSoup(response, "html.parser")  # 指定html解析器,Python会有警告

top = 1
for p in range(5):
    response = requests.get(new_url % p, headers=head).text
    soup = 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").text
        price_div = html_2[i].find("div", class_="price")
        price_lable = price_div.find("p")
        my = price_lable.find("span", attrs={"span", "price_n"}).text
        sy = price_lable.find("span", attrs={"span", "price_r"}).text
        discount = price_lable.find("span", attrs={"span", "price_s"}).text
        print('Top' + str(
            top) + ':' + book_name + '            实洋:' + sy + '          码洋:' + my + '           折扣:' + discount)
        i += 1
        top += 1

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带带琪宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值