• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

第二章-3Python爬虫教程bs4模块、爬取新发地菜价和amp;广州江南果菜批发市场菜价前者数据不在html,后者数据嵌入在html

武飞扬头像
如何原谅奋力过但无声
帮助1

本课程共五个章节,课程地址:

【Python爬虫教程】花9888买的Python爬虫全套教程2021完整版现分享给大家!(已更新项目)——附赠课程与资料_哔哩哔哩_bilibili


第二章

  1. 数据解析概述
  2. 正则表达式
  3. re模块
  4. 手刃豆瓣TOP250电影信息
  5. bs4解析-HTML语法
  6. bs4解析-bs4模块安装和使用
  7. 抓取让你睡不着觉的图片
  8. xpath解析
  9. 抓取猪八戒数据

目录

第二章

(五)bs4解析-HTML语法

标签 

属性

例子 

 (六)bs4解析-bs4模块安装和使用

安装

爬取新发地菜价

爬取广州江南果菜批发市场菜价(bs4)


(五)bs4解析-HTML语法

首先需要了解一些 html 知识,再使用 bs4 去提取

HTML(Hyper Text Markup Language,超文本标记语言)是编写网页最基本也最核心的一种语言,其语法规则就是用不同的标签对网页上的内容进行标记,从而使网页显示出不同的展示效果 

标签 

学新通
不同标签表现出来的效果是不一样的

属性

在标签中还可以给出 xxx=xxx 这样的东西,通过 xxx=xxx 这种形式对标签进一步说明,这种语法在 html 中被称为标签的属性,且属性可以有很多个

  1.  
    <body text="green" bgcolor="#eee">
  2.  
    You see my color
  3.  
    </body>

 学新通

例子 

  1.  
    <h1> i love you </h1>
  2.  
    <h1 align='center'> i don't love you </h1>
  3.  
     
  4.  
    # h1:标签
  5.  
    # align:属性
  6.  
    # center:属性值
  7.  
     
  8.  
    <标签 属性="属性值" 属性="属性值">被标记的内容</标签>
  9.  
    如:<a href="http://www.百度.com">周杰伦</a>
  10.  
     
  11.  
    # 想在网页里引入一张图片,这种标签自带闭合,即<标签 />
  12.  
    <img src="xxx.jpg"/>
  13.  
     
  14.  
    同样的还有<br />
  1.  
    <div id="1" class="h1">周杰伦</div>
  2.  
    <div id="2" class="h1">林俊杰</div>
  3.  
    <div id="3" class="h1">麻花藤</div>
  4.  
    <div id="4" class="h1">天老鸭</div>
  5.  
    <div id="5" class="h4">李多海</div>
  6.  
    <div id="5" class="h5">厉害多</div>
  7.  
    <span>xxxxx</span>
  8.  
     
  9.  
    # 通过标签名称来拿到数据
  10.  
    # div -> id:3 => 麻花藤
  11.  
    # div -> class:h4 => 李多海
  12.  
    # bs4:通过标签的特征来定位到我们想要的内容

bs4 就是通过标签和属性去定位页面上的内容的


 (六)bs4解析-bs4模块安装和使用

安装

在 Terminal 里输入

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4

学新通

bs4在使用的时候需要参照一些 html 的基本语法来进行使用 

爬取新发地菜价

http://www.xinfadi.com.cn/priceDetail.html

学新通  

右键查看网页源代码,发现数据不在html里(跟教学视频有出入,网页改版了,这里不需要用到 bs4 模块) 

学新通

打开抓包工具,可以在 Preview 里看到我们想要的数据都在这里:

学新通

从 Headers 里获取其 url 和 请求方式(为post): 

学新通

post 请求的话就找 Form Data 里的参数,构建字典: 

学新通

  1.  
    import requests
  2.  
     
  3.  
    url = 'http://www.xinfadi.com.cn/getPriceData.html'
  4.  
     
  5.  
    dat = {
  6.  
    "limit":"",
  7.  
    "current":"",
  8.  
    "pubDateStartTime":"",
  9.  
    "pubDateEndTime":"",
  10.  
    "prodPcatid":"",
  11.  
    "prodCatid":"",
  12.  
    "prodName":""
  13.  
    }
  14.  
     
  15.  
    resp = requests.post(url,data=dat)
  16.  
    print(resp.json())
学新通

学新通

将爬取的内容保存到 csv 文件里:

  1.  
    all_count = int(resp.json()["count"])
  2.  
    limit = int(resp.json()["limit"])
  3.  
    all_page_number = int(all_count / limit)
  4.  
     
  5.  
    with open("新发地菜价.csv", mode="a ", newline='',encoding="utf-8") as f:
  6.  
    csvwriter = csv.writer(f)
  7.  
    for i in range(1, all_page_number):
  8.  
    dat1 = {
  9.  
    "limit": limit,
  10.  
    "current": i,
  11.  
    "pubDateStartTime": "",
  12.  
    "pubDateEndTime": "",
  13.  
    "prodPcatid": "",
  14.  
    "prodCatid": "",
  15.  
    "prodName": "",
  16.  
    }
  17.  
    r1 = requests.post(url, data=dat)
  18.  
    list = resp.json()["list"]
  19.  
    count = list
  20.  
    for iter in list:
  21.  
    prodName = iter["prodName"] # 品名
  22.  
    avgPrice = iter["avgPrice"] # 平均价
  23.  
    highPrice = iter["highPrice"] # 最高价
  24.  
    lowPrice = iter["lowPrice"] # 最低价
  25.  
    place = iter["place"] # 产地
  26.  
    prodCat = iter["prodCat"] # 一级分类
  27.  
    pubDate = iter["pubDate"] # 发布日期
  28.  
    unitInfo = iter["unitInfo"] # 单位
  29.  
    csvwriter.writerow([prodName, avgPrice, highPrice, lowPrice, place, prodCat, pubDate, unitInfo])
  30.  
    f.close()
  31.  
    print("Over")
  32.  
     
  33.  
    resp.close()
学新通

完整代码:

  1.  
    import requests
  2.  
    import csv
  3.  
     
  4.  
    url = 'http://www.xinfadi.com.cn/getPriceData.html'
  5.  
     
  6.  
    dat = {
  7.  
    "limit":"",
  8.  
    "current":"",
  9.  
    "pubDateStartTime":"",
  10.  
    "pubDateEndTime":"",
  11.  
    "prodPcatid":"",
  12.  
    "prodCatid":"",
  13.  
    "prodName":""
  14.  
    }
  15.  
    resp = requests.post(url,data=dat)
  16.  
    # print(resp.json())
  17.  
     
  18.  
    all_count = int(resp.json()["count"])
  19.  
    limit = int(resp.json()["limit"])
  20.  
    all_page_number = int(all_count / limit)
  21.  
     
  22.  
    with open("新发地菜价.csv", mode="a ", newline='',encoding="utf-8") as f:
  23.  
    csvwriter = csv.writer(f)
  24.  
    for i in range(1, all_page_number):
  25.  
    dat1 = {
  26.  
    "limit": limit,
  27.  
    "current": i,
  28.  
    "pubDateStartTime": "",
  29.  
    "pubDateEndTime": "",
  30.  
    "prodPcatid": "",
  31.  
    "prodCatid": "",
  32.  
    "prodName": "",
  33.  
    }
  34.  
    r1 = requests.post(url, data=dat)
  35.  
    list = resp.json()["list"]
  36.  
    count = list
  37.  
    for iter in list:
  38.  
    prodName = iter["prodName"] # 品名
  39.  
    avgPrice = iter["avgPrice"] # 平均价
  40.  
    highPrice = iter["highPrice"] # 最高价
  41.  
    lowPrice = iter["lowPrice"] # 最低价
  42.  
    place = iter["place"] # 产地
  43.  
    prodCat = iter["prodCat"] # 一级分类
  44.  
    pubDate = iter["pubDate"] # 发布日期
  45.  
    unitInfo = iter["unitInfo"] # 单位
  46.  
    csvwriter.writerow([prodName, avgPrice, highPrice, lowPrice, place, prodCat, pubDate, unitInfo])
  47.  
    f.close()
  48.  
    print("Over")
  49.  
     
  50.  
    resp.close()
学新通

学新通

由于新发地网站改版了,数据不在页面源代码中了,不需要使用bs4模块。所以我另外找了一个相似的网站,该网站的数据嵌入在html中,以此网站作为案例来使用bs4模块爬取数据 

爬取广州江南果菜批发市场菜价(bs4)

广州江南果菜批发市场 批发市场 最大的水果批发市场 蔬菜批发市场 江南市场

学新通

右键,查看网页源代码,可以看到数据是嵌入在 html 里的

学新通

故接下来的工作可以分为两步:

  1. 拿到页面源代码      见第一步
  2. 使用bs4进行解析,拿到数据       见第二步 ~ 第四步

第一步:拿到页面源代码

  1.  
    import requests
  2.  
     
  3.  
    url = "http://www.jnmarket.net/import/list-1.html"
  4.  
    resp = requests.get(url)
  5.  
    print(resp.text)

第二步:把页面源代码交给BeautifulSoup进行处理,生成bs对象

  1.  
    from bs4 import BeautifulSoup
  2.  
     
  3.  
    # 使用bs4解析数据(两步)
  4.  
     
  5.  
    # 1. 生成bs对象
  6.  
    page = BeautifulSoup(resp.text, "html.parser") # 指定html解析器

第三步:从bs对象中查找数据(通过bs对象去检索页面源代码中的html标签)

BeautifulSoup对象获取html中的内容主要通过两个方法来完成:

  • find()
  • find_all() 

学新通不论是 find 还是 find_all,参数几乎是一致的 

语法:find(标签, 属性=值)    意思是在页面中查找xxx标签,并且标签的xxx属性必须是xxx值

  • 例如,find('div' , age=18) 含义就是在页面中查找div标签,并且属性age必须是18的这个标签

find_all() 用法和 find() 几乎一致。find() 查找一个,find_all() 查找页面中所有的

但是这种写法会有些问题,比如 html 标签中的 class 属性

学新通

若属性名称与python中的关键字一样,可以在属性名称后面加上下划线_以区别

我们还可以使用第二种写法来避免出现此类问题:

学新通 

继续回到正题:

  1. 数据都在这个table表格里,怎么提取呢?       page.find("table") 
  2. 可是页面中如果有多个table呢?   没错,还有一个特殊的class呢。通过 ctrl f 搜索发现页面中只有这一个 price-table,也就是说,如果用  page.find("table",class_="price-table")  就一定能定位到这个表格

学新通

  1.  
    # 2. 从bs对象中查找数据
  2.  
    # find(标签, 属性=值):找第一个
  3.  
    # find_all(标签, 属性=值):找全部
  4.  
     
  5.  
    # table = page.find("table",class_="price-table") # class是python中的关键字,加_以示区别
  6.  
    # 另一种写法:
  7.  
    table = page.find("table",attrs={"class":"price-table"}) # 和上一行是一个意思,此时可以避免class
  8.  
    # print(table)
  9.  
     
  10.  
    # 不想要列名那一行(表头),只想要底下的数据,即拿到所有数据行
  11.  
    trs = table.find_all("tr")[1:] # tr是行的意思
  12.  
    for tr in trs: # 每一行
  13.  
    tds = tr.find_all("td") # td表示单元格。拿到每行中的所有td
  14.  
    # print(tds[0])
  15.  
    # 名字、产地、均价(元/公斤)、规格、日期
  16.  
    name = tds[0].text # .text表示拿到被标签标记的内容
  17.  
    place = tds[1].text
  18.  
    avg_price = tds[2].text
  19.  
    guige = tds[3].text
  20.  
    date = tds[4].text
  21.  
    print(name,place,avg_price,guige,date)
学新通

 学新通

第四步: 将数据保存为csv文件

  1.  
    import csv
  2.  
     
  3.  
    f = open("广州江南菜价.csv",mode="w",newline="",encoding="utf-8")
  4.  
    csvwriter = csv.writer(f)
  5.  
     
  6.  
    table = page.find("table",attrs={"class":"price-table"})
  7.  
     
  8.  
    trs = table.find_all("tr")[1:] # tr是行的意思
  9.  
    for tr in trs: # 每一行
  10.  
    tds = tr.find_all("td") # td表示单元格。拿到每行中的所有td
  11.  
    # print(tds[0])
  12.  
    # 名字、产地、均价(元/公斤)、规格、日期
  13.  
    name = tds[0].text # .text表示拿到被标签标记的内容
  14.  
    place = tds[1].text
  15.  
    avg_price = tds[2].text
  16.  
    guige = tds[3].text
  17.  
    date = tds[4].text
  18.  
    csvwriter.writerow([name,place,avg_price,guige,date])
  19.  
     
  20.  
    f.close()
  21.  
    print("over")
  22.  
     
  23.  
    resp.close()
学新通

学新通

完整代码:

  1.  
    import requests
  2.  
    from bs4 import BeautifulSoup
  3.  
    import csv
  4.  
     
  5.  
    # 拿到页面源代码
  6.  
    url = "http://www.jnmarket.net/import/list-1.html"
  7.  
    resp = requests.get(url)
  8.  
    # print(resp.text)
  9.  
     
  10.  
    f = open("广州江南菜价.csv",mode="w",newline="",encoding="utf-8")
  11.  
    csvwriter = csv.writer(f)
  12.  
     
  13.  
    # 使用bs4解析数据(两步)
  14.  
    # 1. 生成bs对象
  15.  
    page = BeautifulSoup(resp.text, "html.parser") # 指定html解析器
  16.  
     
  17.  
    # 2. 从bs对象中查找数据
  18.  
    # find(标签, 属性=值):找第一个
  19.  
    # find_all(标签, 属性=值):找全部
  20.  
     
  21.  
    # table = page.find("table",class_="price-table") # class是python中的关键字,加_以示区别
  22.  
    # 另一种写法:
  23.  
    table = page.find("table",attrs={"class":"price-table"}) # 和上一行是一个意思,此时可以避免class
  24.  
    # print(table)
  25.  
     
  26.  
    # 不想要列名那一行(表头),只想要底下的数据,即拿到所有数据行
  27.  
    trs = table.find_all("tr")[1:] # tr是行的意思
  28.  
    for tr in trs: # 每一行
  29.  
    tds = tr.find_all("td") # td表示单元格。拿到每行中的所有td
  30.  
    # print(tds[0])
  31.  
    # 名字、产地、均价(元/公斤)、规格、日期
  32.  
    name = tds[0].text # .text表示拿到被标签标记的内容
  33.  
    place = tds[1].text
  34.  
    avg_price = tds[2].text
  35.  
    guige = tds[3].text
  36.  
    date = tds[4].text
  37.  
    # print(name,place,avg_price,guige,date)
  38.  
     
  39.  
    csvwriter.writerow([name,place,avg_price,guige,date])
  40.  
    f.close()
  41.  
    print("over")
  42.  
     
  43.  
    resp.close()
学新通

同理,该代码只爬取了第一页的20条数据,还有优化的空间。翻页的时候注意 url 的变化

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhabhai
系列文章
更多 icon
同类精品
更多 icon
继续加载