阶段学习总结之06

概要

day26 网络爬虫理论

  • 获取数据的途径

  • 爬虫及其分类

  • 网页组成(HTML)

day27 HTML补充知识

  • 特殊符号

  • 常用标签

  • 列表标签

  • 表格标签

  • 表单标签

  • 标签特性

  • 正则表达式

day28 re模块与requests模块的应用

  • re模块

  • 网络请求

  • requests模块(爬虫入门)

day29 cookie与session用法

  • cookie与session

  • 代码模拟用户登录

  • json格式数据

  • ip代理池与cookie代理池

day30 爬虫实战

  • 数据的加载方式

  • 爬取天气数据

  • 爬取百度翻译

  • 爬取药品许可证

  • 多页数据获取与存储

day31 BeautifulSoup4模块与lxml解析器使用

  • 爬虫解析库之bs4模块

  • 爬取红牛分公司数据


详情

day26

  • 获取数据的途径

常见的数据收集网站

1.免费查找
    (1)百度指数:反映出各个关键字在百度的搜索趋势,以及行业发展情况。
https://index.baidu.com/v2/index.html
    (2)新浪指数:通过关键字热议度以及行业/类别影响力,来反映微博舆情或账号的发展情况。
https://data.weibo.com/index
    (3)国家数据/中国政府网:各级政府在互联网上发布政务信息和提供在线服务的综合平台。 # 数据来源于统计局
http://www.gov.cn/shuju/index.htm
    (4)世界银行:获取世界各国的发展数据。# 公开数据
https://data.worldbank.org.cn/
    (5)纳斯达克:世界上主要的股票市场中成长速度最快的市场。
https://www.nasdaq.com/zh/market-activity
    (6)联合国:世界上重要的数据库,涵盖政治、经济、人口、交通、能源等方面。
http://data.un.org/
2.需要付费
    (1)艾瑞咨询:着重于市场研究。 # 国内
https://www.iresearch.com.cn/
    (2)埃森哲:https://www.accenture.com/cn-zh
       麦肯锡:https://www.mckinsey.com.cn/ # 国外
    (3)数据堂:https://www.datatang.com/ # 第三方
       贵阳大数据:http://gbdex.bdgstore.cn/
  • 爬虫及其分类

爬虫理论
# 爬虫技术基于互联网
1.什么是互联网?
    互联网是由网络设备(网线、路由器、交换机、防火墙等)和一台台计算机连接而成,形成的一张巨大的网。
2.建立互联网的目的?
    数据存放在多台设备上,将其互联能大幅提升数据共享/传输的效率。 # 否则就得去设备物理所在地拷贝数据
3.上网的本质?
    上网的本质是由用户计算机向目标发送请求并将其存放在本地的数据传输到用户本地的过程。
4.爬虫的功能?
    爬虫是通过代码模拟网络请求(人的行为)获取并分析数据的过程。 # 比人为查找数据效率高
5.爬虫的价值?
    先来做个比喻
    互联网     ->      蜘蛛网
    数据       ->      猎物
    爬虫程序    ->      想要顺着蜘蛛网捕猎的小蜘蛛
其中,数据是核心,如天猫商品信息、链家租房信息等。
掌握爬虫技能,就掌握行业第一手资料。
爬虫分类
爬虫分为两种:
1.通用爬虫:搜索引擎使用的爬虫系统
    尽可能地把互联网上所有的网页下载下来放到本地形成备份,再进行处理(提取关键字、去除广告等),组合成检索结果呈现给用户。
    (1)搜索引擎获取url的过程:
        1.主动提供 https://ziyuan.baidu.com/site/index
        2.在各大网站设置外链(友情链接)
        3.与DNS服务商合作(域名解析) ping URL -t
2.聚焦爬虫:爬虫相关程序员编写的有针对内容的爬虫程序
  • 网页组成(HTML)

'''HTML 即超文本标记语言'''
    我们使用浏览器看到的画面是通过HTML代码展现的,爬虫程序就是从大量HTML代码中筛选需要的数据。
# 前端
与用户直接交互的界面。
# 后端
由程序员编写的实现程序内部业务逻辑的代码,不直接与用户打交道。
前端一般由三种语言构成
1.HTML           超文本标记语言 构成网页的整体
作用:通过一系列标签统一网页的文档格式。
2.CSS           层叠样式表     构成网页的样式
作用:对网页中元素位置的排版进行像素级的精确控制。
3.JavaScript(JS) 一种脚本语言    构成网页的动态效果
作用:为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。
HTML的基本组成
网页文件一般以.html结尾
语法
<html>
    <head>供浏览器识别的数据</head>
    <body>
        展现给用户的数据
    </body>
</html>
<!-- head部分常见标签 -->
<title>定义网页标题</title>
<style>css代码</style>
<link>引入外部css文件
<script>js代码/引入js文件</script>
<meta>定义网页源信息
eg: <!-- 关键字 -->
    <meta name="keywords" content="HTML 教程,html">
    <!-- 摘要/描述 -->
    <meta name="description" content="HTML 教程- (HTML5 标准)  超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点,HTML 运行在浏览器上,由浏览器来解析。 在本教程中,您将学习如何使用 HTML 来创建站点。 HTML 很容易学习!相信您能很快学会它!   HTML 实例 本教程包含了数百个 HTML 实例。 使用本站的编辑器,您可..">
body常见标签
html标签分类
1.双标签(有头有尾)   <a></a>
2.单标签(自闭和)     <img>
基本标签
<h1></h1> ~ <h6></h6> 大小各不相同的标题
<a></a> 网页链接
<img> 图像
<u></u> 下划线
<s></s> 删除线
<i></i> 斜体字
<b></b> 粗体字
<p></p> 段落
<hr> 水平分割线
<br> 换行
 

day27 HTML补充知识

  • 特殊符号

特殊符号会与标签格式冲突,在HTML中需要进行转义
空格   &nbsp
>      &gt;
<      &lt;
&      &amp;
¥     &yen;
版权©  &copy;
注册®  &reg;
  • 常用标签

<!-- 链接标签 -->
<a href="https://www.baidu.com"点这里打开百度</a>
参数href是网址,点击标签文本即可跳转到该网页
<!-- 图片标签 -->
<img src="" title="" alt="">
参数src是图片地址,可以是本地的也可以是网络上的
参数alt是图片无法显示时替换的备用文本
参数title是鼠标悬浮图片上时显示的文本
<!-- 页面布局 -->
<div></div>
是所有网页中出现频率最高的标签,用于划分页面布局,可以无限制嵌套任何标签
<!-- 页面文本 -->
在网页中出现频率没有div标签高,用于显示文本
  • 列表标签

<!-- 一般用于显示网页上规则排列的横向/竖向的内容 -->
<ul>
    <li>00A</li>
    <li>00B</li>
    <li>00C</li>
</ul>
  • 表格标签

<!-- 一般用于以表格的形式显示相同格式的数据 -->
<table border="2">
<!-- 表格标签 border指定边框厚度 -->
    <thead><!-- 表头(记录字段) -->
        <tr><!-- 一个tr就是一行 -->
            <th>书名</th><!-- 字段名 -->
            <th>作者</th><!-- 字段名 -->
            <th>出版社</th><!-- 字段名 -->
        </tr>
    </thead>
    <tbody><!-- 表体(记录数据值) -->
        <tr><!-- 第一条数据(第一行) -->
            <td>Python编程</td><!-- 字段值 -->
            <td>埃里克.马瑟斯</td><!-- 字段值 --> 
            <td>人民邮电出版社</td><!-- 字段值 --> 
        </tr>
        <tr><!-- 第二条数据(第二行) -->
            <td>Pyhton游戏</td>
            <td>Jonathan S.Harbour</td>
            <td>人民邮电出版社</td>
        </tr>
    </tbody>
</table>
  • 表单标签

获取用户输入的数据需要使用表单标签,一般放在用form标签中。

1.输入框   <!-- 参数type是输入的类型 -->
<input type="">
text        普通文本
password    密文展示(用于输入各类密码)
email       邮箱格式
date        日期格式
radio       单选(选项设为相同name参数即为单选)
checkbox    多选
file        文件
submit      提交按钮(提交表单数据的操作)
reset       重置按钮
button      自定义按钮
2.文本域   <!-- 用于输入大段文本(多行) -->
<textarea></textarea>
3.选择标签(参数multiple="True"即为多选)
<select multiple="">
    <option></option><!-- 选项 -->
</select>
  • 标签特性

<a id="" class=""></a>
以a标签为例,id和class等称为该标签的属性
<!-- id和class是标签的两大核心属性 -->
<!-- 类似于某个学生的学号 -->
id     唯一标识某个标签,在同一个.html文件中不能重复
<!-- 类似于某些学生的班级 -->
class  给标签区分类别,用于同时查找多个标签,可重复
eg:
        <p class='p1'></p>
        <a class='a1'></a>
        <div class='d1'></div>
        <!-- 一个标签可以含有多个class值 -->
        <span class='s1 s2 s3'></span>
<!-- 标签可以拥有自定义属性,一般用于携带额外数据 -->
<a username="Leoric" pwd="好好学习天天向上"></a>
<!-- 标签之间的关系 -->
<div>div内部的标签都称为div的后代
    <a>上一级div的儿子</a>
    <p>上一级div的儿子
        <span>上一级p的儿子上上一级div的孙子</span>
    </p>
    <div>上一级div的儿子
        <a>上一级div的儿子上上一级div的孙子</a>
    </div>
    <span>上一级div的儿子</span>
</div>
  • 正则表达式

使用场景:简化数据筛选
用纯python流程控制实现手机号的校验太过繁琐!!!    使用正则表达式可以简化步骤
# 引入正则表达式匹配文本的re模块
import re
phoneNum=input('请输入手机号:')
if re.match('^(13|14|15|18)[0-9]{9}$',phoneNum)
    print('手机号格式正确')
else:
    print('手机号格式错误')
# 当然,匹配内容精确时就直接书写具体内容即可
字符组
字符组匹配内容时都是循环按单个字符匹配
[0123456789] 匹配0-9之间任意一个数字包括首尾
[0-9] 简写,同上
[a-z] 匹配小写字母a-z之间任意一个字母包括首尾
[A-Z] 匹配大写字母A-Z之间任意一个字母包括首尾
[0-9a-zA-Z]匹配数字或者小写字母或者大写字母
符号
符号匹配内容时都是循环按单个字符匹配
.           匹配除换行符以外任意字符
\d          匹配数字
^           匹配字符串开始
[^....]     匹配除中括号内^后的字符组以外任意字符
[]          匹配中括号内的字符
$           匹配字符串结尾
a|b         匹配字符a或者字符b
()          给正则表达式分组,本身无含义
量词
符号放在字符组后面可以指定匹配个数
不能单独使用
*       重复零次或更多次
+       重复一次或更多次
?       重复零次或一次
{n}     重复n次
{n,}    重复n次或更多次
{n,m}   重复n到m次
# 默认贪婪匹配,尽可能多地匹配字符
<script>123</script>
<.*>  匹配结果:一个结果 <script>123</script>
# 在量词后加一个问号皆可切换为非贪婪匹配
<.*?> 匹配结果:两个结果 <script></script>

day28 re模块与requests模块的应用

  • re模块

# 常用方法
1.findall(正则表达式,待匹配文本)
返回所有满足匹配条件的结果,存放于列表中
() 分组并优先展示,在括号内左边加 ?: 为无效优先展示
2.finditer(正则表达式,待匹配文本)
返回一个迭代器,主动索要可产生索要匹配结果(使用循环),
否则只占用一块名称空间
3.match(正则表达式,待匹配文本)
从头开始匹配文本,文本头部不符合就停止匹配并返回空
4.search(正则表达式,待匹配文本)
只匹配第一个符合正则的数据,匹配到就停止后续匹配
  • 网络请求

# get请求
向服务器索要数据(例如在浏览器地址栏输入网址并按回车)
get请求可携带额外数据,大小限制为2~4KB,数据以K:V键值对的形式书写与网络地址后
格式: 网络地址后大量用&分割的a=b
# post请求
向服务器提交数据(例如常见的用户注册/登录输入用户名和密码后点击提交)
post请求可以携带额外数据,大小无限制,一般用于敏感数据,数据存放于请求体中
格式: Form Data中的数据

HTTP协议

HTTP协议统一了浏览器与服务端之间交互数据的方式
1.四大特性
    (1)基于请求响应
        服务端不会主动向客户端发送请求,只会被动接受请求
    (2)基于TCP/IP作用于应用层之上的协议
    (3)无状态
        不保存客户端的状态,每个请求均是相互独立的
    (4)无连接
        不会占用过多资源
        限制每次连接只处理一个请求,收到客户端请求处理完响应并收到客户端的应答后即断开连接
2.数据请求格式
    请求数据
        请求首行(方法、地址等)
        请求头(由K:V键值对携带的信息)
        
        请求体(get请求:无  post请求:用于携带敏感数据)
    响应数据
        响应首行(状态码、协议版本等)
        响应头(由K:V键值对携带的信息)
        
        响应体(浏览器展现给用户的数据)
3.响应状态码
    简单的数字表示各种响应状态
    1XX:服务器成功接收到数据,正在处理,可继续提交或者等待
    2XX:常见的如200,请求成功,服务器成功响应
    3XX:重定向(某些条件下点击跳转到另外的界面,如淘宝未登录点击商品)
    4XX:403:请求不符合条件(权限不够);404:请求资源不存在
    5XX:服务器内部错误,与客户端无关
"""状态码可以自定义,http协议自带的太少"""
    自定义状态码一般由10000开始,可在一些网站如聚合数据中看到
  • requests模块(爬虫入门)

# requests模块是第三方模块,需要下载 
pip3 install requests
# 引入该模块
import requests
该模块可用于发送网络请求
requests.get(url)     # 发送get请求
requests.post(url)    # 发送post请求
"""具体使用"""
# 简单的get请求获取页面
1.发送请求
res = requests.get('https://www.bilibili.com/')
print(res.status_code)  # 获取响应状态码
print(res.text)         # 获取网页字符串数据
print(res.content)      # 获取页面二进制数据
2.指定字符编码
res.encoding = 'UTF-8'
3.将页面数据写入文件
with open(r'bilibili.html', 'wb') as f:
        f.write(res.content)
        
# 携带参数的get请求获取页面 
requests.get(url,params={'参数键':'参数值'})
eg:
res = requests.get('https://www.baidu.com/s',
                   params={
                      'wd': '奥特曼'
                   }) # 获取失败
res = requests.get('https://search.bilibili.com/all',
                   params={
                      'keyword': '奥特曼'
                   }) # 获取成功
# 携带请求头数据的get请求获取页面
requests.get(url,headers={'请求头键':'请求头值'})
eg:
res = requests.get('https://www.baidu.com/s',
                   params={
                       'wd': '奥特曼'
                   },
                   headers={
                       'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'
                   })

防爬措施

最基础的
1.校验当前请求是不是由浏览器发出的
    查看请求头内的User-Agent键值对,有这个键值对说明是浏览器
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36
    措施:在请求头中加上该键值对
        requests.get(url,headers={...})

day29 cookie与session用法

  • cookie与session

cookie和session的诞生是为了解决http协议无状态的特性在使用上的不便。
定义:
    1.cookie:保存在客户端的键值对数据
    原理:用户首次登录网站成功,浏览器会保存使用的用户名和密码等数据,之后再次访问的请求携带用户名和密码 
    2.session:保存在服务端的用户相关数据
    原理:用户首次登录网站成功,服务端会返回给客户端一个或多个随机字符串,客户端保存该字符串,之后再次访问的请求只需携带该随机字符串即可
session的使用必须基于cookie功能
# cookie实践
在浏览器->检查->network中可以看到,请求体的关键字是Form Data
eg: 网址:http://www.aa7a.cn/user.php  # 校验用户名和密码的接口
    请求体格式:
        username: xxxxxx
        password: xxxxxx
        captcha: jv3d
        remember: 1
        ref: http://www.aa7a.cn/user.php?act=logout
        act: act_login
"""研究爬虫的流程!!!"""
1.找到登录时提交数据的目标url地址
2.了解登录post请求携带的请求体数据格式
3.模拟发送post请求
  • 代码模拟用户登录

搞清楚向服务端发送的请求,就为实现利用代码模拟用户在网页登录提供了可能。

import requests
testUrl = 'http://www.aa7a.cn/user.php'
# 登录时发送的post请求的请求体
postR = {
    "username": "423168031@qq.com",
    "password": "123123",
    "captcha": "z2ft",
    "remember": 1,
    "ref": "http://www.aa7a.cn/?act=logout",
    "act": "act_login"
}
# 发送post请求,data参数是请求体数据
res = requests.post(testUrl, data=postR)
#获取登录成功后浏览器收到的cookie数据
print(res.cookies.get_dict())
"""用户名和密码均正确"""
# 返回的cookie数据
cookieDict = {
     'ECS[password]': '4297f44b13955235245b2497399d7a93',
     'ECS[user_id]': '67327',
     'ECS[username]': '423168031%40qq.com',
     'ECS[visit_times]': '1',
     'ECS_ID': 'e5cf79f8784ecd0bcfce57d6944719249757e7da'
}
# 使用上述正确的cookie登录网站
resG = requests.get(testUrl,cookies=cookieDict)
if "423168031@qq.com" in resG.text:
    print('登陆成功')
else:
    print('cookie有问题')

Json格式数据

response.content一下子获取较大数据过于消耗内存
解决方案:设置stream参数
# 比如读取一个200G的视频
response=requests.get(url,stream=True)
with open('b.mp4','wb') as f:
    for line in response.iter_content():  # 逐行读取内容
        f.write(line)
 
# 网络上包括爬虫相关,很多数据交互均采用json格式
json特点:数据由双引号标识
json()方法:将json格式数据反序列化转换成Python中对应的其他数据类型
eg:    
res = requests.get(url)
res.json()
  • ip代理池与cookie代理池

1.IP代理池
有些网站会使用限制一定时间内客户端同一个ip地址访问的防爬措施
eg:
    1min之内同一个ip地址的访问次数不能超过30次,否则禁止该ip访问
解决方案:
    使用IP代理池(由另外的ip地址代替该ip发送请求)
格式: # 每个ip均限制特定的端口
    proxies={
    'http':'114.99.223.131:8888',
    'http':'119.7.145.201:8080',
    'http':'175.155.142.28:8080'   
    }
    response=requests.get(url,proxies=proxies)
这样,每次发送网络请求时,会从代理池中随机选择ip代替本机访问该网页
​
2.cookie代理池
有些网站会使用对客户端cookie数据(即登录的账户)进行校验的防爬措施
eg:
    1min之内同一个cookie的登录次数不能超过30次,否则禁止该cookie访问
格式:
    resposne=requests.get(url,cookies={})
# 备用的cookie需要自行模拟

day30 爬虫实战

  • 数据加载方式

# 常见的加载方式
1.直接加载
朝服务器发送网络请求,返回全部页面数据并加载
2.间接加载(内部JS代码多次请求)
朝服务器发送网络请求,先返回页面主体结构并加载,再朝其他地址发送请求以获取具体数据

爬取天气数据

思路:
    1.打开页面,先分析从数据加载的方式(空白处右键查看网页源代码)
    2.源代码中并无天气数据,此页面为间接加载
    3.查看打开该网页时会向哪些网址发送请求(空白处右键检查选network,get请求可直接将地址复制到浏览器地址栏访问)
    4.分析请求得到的结果是否是天气数据
      解析json字符串的网站:https://www.bejson.com/
    5.如果是就利用requests模块朝该地址发送get请求获取json数据
    6.分析历史天气url的规律,可爬取其他月份的数据import requests
urlW = 'http://tianqi.2345.com/Pc/GetHistory?areaInfo%5BareaId%5D=60010&areaInfo%5BareaType%5D=2&date%5Byear%5D=2021&date%5Bmonth%5D=9'
res = requests.get(urlW)
dictW = res.json().get('data')
print(dictW)
  • 爬取百度翻译

思路:
    1.打开页面,先分析从数据加载的方式(空白处右键查看网页源代码)
    2.源代码中并无输入单词的信息,此页面为间接加载
    3.该网页对单词的翻译是随着输入框变动动态获取的
    4.打开network,发现每次输入单词都会朝四个地址发送请求,其中sug频率固定
      解析json字符串的网站:https://www.bejson.com/
    5.利用requests模块朝sug请求的地址发送post请求获取json数据
        该请求用于显示输入框下拉菜单的数据import requests
urlEng = 'https://fanyi.baidu.com/sug'
# 搜索框下拉数据
resE = requests.post(urlEng,
                     headers={
                         'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36X-Requested-With: XMLHttpRequest'},
                     data={
                         'kw': 'q'
                     })
dataE = resE.json().get('data')
for d in dataE:
    print(d)
  • 爬取药品许可证(单页)

http://scxk.nmpa.gov.cn:81/xk/
思路:
1.打开页面,先分析从数据加载的方式(空白处右键查看网页源代码)
2.源代码中并无药企信息,此页面为间接加载
3.查看打开该网页时会向哪些网址发送请求
4.发现打开页面时会向一个地址发送post请求,查看其请求体
5.利用requests模块朝sug请求的地址发送post请求获取json数据
6.继续验证详情页的数据加载方式# 1.引入requests模块用于发送网络请求
import requests
# 2.指定查找药企概要信息的url
urlXkzsList = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
# 3.指定查找详情的url
urlXkzsDetail = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
# 4.将请求体信息放入post请求并向概要url发送
res = requests.post(urlXkzsList,
                    data={
                        'on': 'true',
                        'page': 1,      # 页码
                        'pageSize': 15, # 每页数据行数
                        'productName': '',
                        'conditionType': 1,
                        'applyname': '',
                        'applysn': ''
                    })
# 5.获取上述的响应,为单页药企概要信息
dataList = res.json().get('list')
# 6.循环获取每家药企的信息
for d in dataList:
    # 7.向每家药企发送携带企业ID的post请求
    resD = requests.post(urlXkzsDetail, data={'id': d.get('ID')})
    # 8.将请求结果(单家药企信息)反序列化成字典
    resDict = resD.json()
    # 9.输出该企业信息
    print(resDict)
  • 多页数据获取与存储

思路:
1.先点击页码在network查看请求url的变化
    (1)如果数据变化且url不变 那么数据肯定是动态加载的
    (2)如果数据变化且url变 那么数据可能是直接加载或动态加载
2.针对上述案例,数据是动态加载,所以需要研究每一次点击页码内部请求
3.研究请求体参数得知数据页由page表示
4.在外层加一个for循环
5.将数据逐次存入文件

day31 BeautifulSoup4模块与lxml解析器使用

  • 爬虫解析库之bs4模块

# 需要下载 Beautiful Soup4
    1.是一个可以从HTML或XML文件中提取数据的Python库
    2.通过特定的解析器实现惯用的文档导航,查找,修改文档的方式
bs4模块基本使用
# 构造一个bs4解析器对象
soup = BeautifulSoup(htmlDoc, 'lxml')
重要,必须掌握
1.soup.标签名 返回从上往下第一个该标签
eg:soup.a
2.soup.标签名.text 返回标签内部的文本,包含后代所有的文本
eg:soup.p.text
3.soup.a.attrs 返回标签内部所有属性(字典的数据类型)
eg:soup.a.attrs
4.soup.标签名.attrs.get('属性名')
也可简写为 soup.标签名.get('属性名')
返回某标签的指定属性值
eg: soup.a.attrs.get('href')
    soup.a.get('href')
了解即可
1.soup.标签名.children 
返回标签内部所有的子标签,是个迭代器需要循环取值
eg:soup.p.children
   for i in soup.p.children:
       print(i)
2.soup.标签名.contents 
返回标签内部所有元素(列表的数据类型,包含换行符等)
eg:soup.p.contents
3.soup.标签名.parent 返回该标签的父标签
  soup.标签名.parents 返回该标签的所有祖先标签
eg:soup.p.parent
   soup.p.parents
"""核心操作"""
1.find(条件) 查找符合条件的第一个标签对象
eg:
    soup.find(name='a')
    soup.find(name='a', id='link2')
2.避免冲突:冲突的关键字可加下划线区分,也可作为键值对放入attrs参数中
    soup.find(冲突参数_='')
    soup.find(attrs={'冲突参数':''})
eg:
    soup.find(name='p',class_='title')
    soup.find(name='p',attrs={'class':'title'})
# class属性查找属于成员运算,不加name参数查找该类别下所有标签
    soup.find(attrs={'class':'title'})
3.find_all() 查找所有符合条件的标签(列表的数据类型)
    soup.find_all(条件)
eg:
    soup.find_all('a') 
    # name参数可省,其他使用方法一致
4.select(参数) 参数是css选择器,返回列表
css选择器
    (1)标签选择器
    标签名
    (2)id选择器
    #id名   id='id'
    eg:#d1   等价于id='d1'
    (3)class选择器
    .class名  class='class名'
    eg:.c1   等价于class='c1'
    (4)子标签选择器
    标签名>子标签名   查找标签内部所有的该子标签
    eg:div>p
    (5)后代标签选择器
    标签名 后代标签名  查找标签内部所有的该后代标签
    eg:div p
使用案例:
    1.soup.select('.title')
    查找class含有title的标签
    2.soup.select('.title b')
    查找class含有title的标签的所有后代b标签
    3.soup.select('#link1')
    查找id等于link1的标签
    4.soup.select('#link1 sqan')
    查找id等于link1的标签的所有后代span标签
    5.soup.select('#list-2 .element')
    查找id等于list-2的标签的所有class为element的后代标签
    6.soup.select('#list-2')[0].select('.element')
    # select可以连续使用 很少用
    查找id为list-2的第一个标签的所有class为element的后代标签
 
  • 爬取红牛分公司数据

需求:获取红牛所有分公司详细数据(名称、地址、邮箱、电话)

1、查找数据加载方式 得知是直接加载的

2、朝该网页发送请求获取页面数据之后筛选即可

import requests
from bs4 import BeautifulSoup

数据就在页面上显示,直接发送请求即可
res = requests.get('http://www.redbull.com.cn/about/branch')
soup = BeautifulSoup(res.text, 'lxml')
# 1.获取分公司名称
h2List = soup.find_all('h2')
nameList = [tag.text for tag in h2List]
# 2.获取分公司地址
p1List = soup.find_all(name='p', attrs={'class': 'mapIco'})
addrList = [tag.text for tag in p1List]
# 3.获取分公司邮编
p2List = soup.find_all(name='p', attrs={'class': 'mailIco'})
postalCodeList = [tag.text for tag in p2List]
# 4.获取分公司电话
p3List = soup.find_all(name='p', attrs={'class': 'telIco'})
phoneList = [tag.text for tag in p3List]
# 5.将获取到的分公司数据一一对应(按照名称循环)
for i in range(len(nameList)):
    print("""
    公司名称:{}
    公司地址:{}
    公司邮箱:{}
    公司电话:{} 
    """.format(nameList[i], addrList[i], postalCodeList[i], phoneList[i])
          )
posted @ 2021-09-20 11:36  Leguan001  阅读(67)  评论(0)    收藏  举报