• python 网络爬虫全流程教学,从入门到实战(requests+bs4+存储文件)


    python 网络爬虫全流程教学,从入门到实战(requests+bs4+存储文件)

    requests是一个Python第三方库,用于向URL地址发起请求
    bs4 全名 BeautifulSoup4,是编写 python 爬虫常用库之一,主要用来解析 html 标签。


    一、爬虫编写过程解析

    1.1 导入库文件(请求库、解析库)

    #导入 requests请求库
    import requests
    
    #导入bs4解析库
    from bs4 import BeautifulSoup
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果没有上面的两个库文件可以通过以下两种方式安装:
    方式一:去cmd命令窗口中输入:pip install requests 和 pip install BeautifulSoup4 命令。
    方式二:通过在 Pycharm 里面安装:file > settings 接下来就是如下图所示:在这里插入图片描述

    1.2 发起对指定网页的请求

    #对爬取网页的链接
    url='请求地址'
    
    #请求头(作用:为了不被对方发现是爬虫的访问)
    #去需要爬取网页上>打开开发者模式(F12)>网络(network)>随便点开一个文件>标头>请求头里的User-Agent
    headers={'User-Agent': '请求头'}
    
    #发起get请求,获取请求内容,并用(utf-8)解码(编码一般是:utf-8,gbk,gb2312)
    html=requests.get(headers=headers,url=url).content.decode('utf-8')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.3 解析为 bs4格式

    #解析为bs4,BeautifulSoup(html文本,'解析器'),如下表
    soup=BeautifulSoup(html,'html.parser')
    
    • 1
    • 2

    如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的。

    解析器使用方法优势
    Python标准库BeautifulSoup(html, “html.parser”)1、Python的内置标准库 2、执行速度适中 3、文档容错能力强
    lxml HTMLBeautifulSoup(html, “lxml”)1、速度快 2、文档容错能力强
    lxml XMLBeautifulSoup(html, [“lxml”, “xml”]) BeautifulSoup(html, “xml”)1、速度快 2、唯一支持XML的解析器
    html5libBeautifulSoup(html, “html5lib”)1、最好的容错性 2、以浏览器的方式解析文档 3、生成HTML5格式的文档

    1.4 解析获取的内容(获取想要的数据)

    #获取想要的网页标签(如div)
    Tdiv=soup.find_all('div',class_="div的class样式名")
    
    #输出查找到的结构
    print(Tdiv)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.5 存储爬取的数据

    #格式
    with open('./文件路径/文件名.文件类型','权限') as f:
    	f.write('字符型文本')
    
    • 1
    • 2
    • 3



    二、bs4核心函数

    作用:获取,网页中的各个自己想要的标签,一般是从大标签到小标签的过程

    操作案例百度

    #导入库
    from bs4 import BeautifulSoup
    import requests
    
    #百度的url地址
    url="https://www.baidu.com/"
    #请求头(作用:为了不被对方发现是爬虫的访问)
    hearders={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.53'}
    #获取百度的请求
    html=requests.get(url=url, headers=hearders).content.decode("utf-8")
    #解析为bs4
    soup = BeautifulSoup(html,"html.parser")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.1 find()

    查找符合条件的第一个标签,结果是标签对象

    find( name , attrs/class_ , recursive , string , **kwargs )

    soup.find(‘标签名’,属性名=“属性”/class_=“类名”,recursive=“是否只要子节点(默认False)”,string=“标签内容”)

    参数可以任意组合或只填写一个


    ①根据标签名定位第一个指定的标签
    #查询出第一个p标签对象,并输出
    print(soup.find('p'))
    
    #查询出第一个a标签对象,并输出
    print(soup.find('a'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ②根据属性名定位满足条件的第一个标签
    #查询class属性为’s-top-wrap s-isindex-wrap‘的任意标签
    print(soup.find(class_='s-top-wrap s-isindex-wrap'))
    
    #查询id属性为s_top_wrap的所有标签,其他属性名照写
    print(soup.find(id='s_top_wrap'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ③根据标签和标签属性定位
    #查询class为’s-top-wrap s-isindex-wrap‘的一个div标签
    print(soup.find('div',class_='s-top-wrap s-isindex-wrap'))
    
    #查询id为s_top_wrap的第一个div标签
    print(soup.find('div',id='s_top_wrap'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ④根据指定的标签名和对应的标签内容定位
    #查询到内容为“设置“的第一个span标签
    print(soup.find('span',string="设置"))
    
    • 1
    • 2

    2.2 find_all()

    find()函数用法一样,不同之处在于find()只返回满足条件的第一个标签对象,而find_all()返回所有满足条件的标签对象,是一个列表。有时需要两个配合使用。


    ①根据标签名定位所有指定的标签
    #查询所有是img的标签,返回的是一个列表
    print(soup.find_all('img'))
    
    • 1
    • 2

    ②根据属性名定位所有满足条件的标签
    #查询所有class属性为’s-top-wrap s-isindex-wrap‘的任意标签
    print(soup.find_all(class_='s-top-wrap s-isindex-wrap'))
    
    #查询id属性为s_top_wrap的所有标签,其他属性名照写
    print(soup.find_all(id='s_top_wrap'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ③根据指定的标签和对应的属性名定位所有满足条件的标签
    #查询所有class属性为's-top-wrap s-isindex-wrap'的div标签
    print(soup.find_all('div',class_='s-top-wrap s-isindex-wrap'))
    
    #查询所有id属性为's_top_wrap'的div的标签
    print(soup.find_all('div',id='s_top_wrap'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ④根据指定的标签名和对应的标签内容定位
    #查询内容为“设置“的所有span标签
    print(soup.find_all('span',string="设置"))
    
    • 1
    • 2

    2.3 select()

    select()函数也是定位所有满足条件的标签,返回值也是一个列表


    ①根据标签名定位
    #查询所有是img的标签,返回的是一个列表
    print(soup.select("img"))
    
    • 1
    • 2

    ②根据标签名和属性定位
    #查询class属性为’s-top-wrap‘的所有标签
    print(soup.select('.s-top-wrap'))
    
    #查询id属性为‘s_top_wrap'的所有标签
    print(soup.select('#s_top_wrap'))
    
    #通过标签名和属性一起配合查询,其他属性直接写对应的属性如:a[hrsr='https']
    print(soup.select('div[id="s_top_wrap"]'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ③定位对应的子标签
    #查所有a标签下的img标签
    print(soup.select('a>img'))
    
    • 1
    • 2



    三、bs4基本操作

    作用:获取标签中自己想要的内容,如:文字、图片链接、视频链接、音频链接等

    注意:soup只是一个变量,就是你查询出来后新的获取范围


    3.1 获取标签内的文本

    #分别获取a标签和p标签内的文本内容(推荐第一种方式)
    print(soup.a.text)
    print(soup.p.string)
    
    • 1
    • 2
    • 3

    3.2 获取标签属性

    #获取第一个div标签的所有属性
    print(soup.div.attrs)
    
    • 1
    • 2

    3.3 获取指定标签的属性值

    #获取div标签中的class属性的值
    print(soup.div.attrs.get('class'))
    
    #获取div标签中的id属性的值
    print(soup.div.get('id'))
    
    #获取img标签中的src属性的值
    print(soup.img.get('src'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.4 遍历获取的标签的属性值

    #获取到所有的img标签,返回值为列表
    imgs=soup.find_all('img')
    for i in imgs:
        #img标签中src的值
        print(i['src'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    #获取到所有的img标签,返回值为列表
    imgs=soup.find_all('img')
    for i in imgs:
        #img标签中src的值
        print(i.get('src'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.5 获取指定标签内所有的元素

    print(soup.p.contents)
    
    • 1

    3.6 获取标签的父标签

    print(soup.a.parent)
    
    • 1



    四、存储数据

    1、存储为:文本文档(txt)、表格(excel)、图片、音频、视频
    2、写出媒体思路:①在网页上找到媒体链接;②保存媒体链接;③向媒体链接发起请求;④通过返回的请求内容下载媒体

    3、注意:本章节只讲解写操作,写出什么文件写什么格式


    4.1 with open() as f: 用法

    #格式
    with open('./文件路径/文件名.文件类型','权限') as f:
    	f.write('字符型文本')
    
    • 1
    • 2
    • 3
    权限作用
    r读 取 ,读取文件里的内容
    w写入,新的会覆盖旧的
    a写入,在末尾追加写入,不会覆盖旧的
    wb写入,以二进制的方式写入(图片、音频、视频)

    4.2 写入为文本文档(txt)

    #将变量里的内容写入到“文本.txt”文件中,没有"文本.txt"会自动创建
    wb='我是被爬取下来的文字'
    with open('文本.txt','w') as f:
        f.write(wb)
    
    • 1
    • 2
    • 3
    • 4

    4.3 循环写入到文本文档中(txt)

    #将列表里的内容循环到“文本.txt”文件中,没有"文本.txt"会自动创建
    wb=['文本1','文本2','文本3','文本4']
    for i in wb:
        with open('文本.txt','a') as f:
        	f.write(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.4 存储图片

    #导入请求库
    import requests
    
    #请求头
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42'}
    
    #图片地址列表
    imgs=['https://img-blog.csdnimg.cn/a263ea6716ff44d4a2a825dbf26d2666.png','https://img-blog.csdnimg.cn/43112c81ed164acfb45295f516d08925.png']
    
    #为图片命名的变量
    i=1
    
    #遍历图片地址
    for img in imgs:
        #向图片地址发起请求,并且获取请求内容
        res=requests.get(url=img,headers=headers).content
        #写出图片(注意:权限是wb,写图片扩展名和获取的图片保存一致)
        with open(str(i)+'.png','wb') as f:
            #写出的参数为请求回来的内容
        	f.write(res)
        i+=1
    print("写出成功!")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4.5 存储视频

    写出音频也是如此

    #导入库
    import requests
    
    #请求头
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42'}
    
    #视频地址
    video='https://prod-streaming-video-msn-com.akamaized.net/3f6ca508-598d-4cbd-a3e2-43deea7bc377/b60c553e-9f3f-4164-8850-700a9a73a899.mp4'
    
    #发起请求
    res=requests.get(url=video,headers=headers).content
    
    #写出视频
    with open('视频.mp4','wb') as f:
        f.write(res)
    print("写出成功!")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.6 存储为excel

    sheet.write(行,列,内容)

    注意:行和列都是从0开始的,保存的格式为:.xls

    #导入写出excel的库
    import xlwt
    
    #写入的数据
    tn=['姓名','性别','年龄']
    wb=['玲华','女','18']
    #1、创建Workbook对象,就是创建Excel文件
    work_boot=xlwt.Workbook(encoding='utf-8');
    
    #2、创建sheet表单
    sheet=work_boot.add_sheet('formName') #formName为表单名称
    
    #3、写入内容
    for i in range(len(wb)):
        sheet.write(0,i,tn[i])   #write(行,列,内容)
        sheet.write(1,i,wb[i])
    
    #保存文件
    work_boot.save("个人信息.xls")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19



    五、爬虫实战操作

    实战是需要自己去分析网页结构的,博主代码只是一种参考,还是要自己去分析。


    5.1 百度热搜榜

    获取标题、热度、简介、新闻链接、图片、文本保存为txt,并输出

    注意:这里没有自动创建保存文件的文件夹,自行修改

    #导入库文件
    import requests
    from bs4 import BeautifulSoup
    
    #请求头
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42'}
    #请求地址
    url='https://top.baidu.com/board?tab=realtime'
    
    def Hot_search():
            #发起请求
            html=requests.get(url=url,headers=headers).text;
            #解析为bs4
            res=BeautifulSoup(html,"html.parser")
            #获取类名获取指定的div(包含所有的新闻信息)
            news_div=res.find_all("div",class_="category-wrap_iQLoo horizontal_1eKyQ")
            #遍历div(提取每一个新闻)
            for new in news_div:
                try:
                    #获取新闻的标题(标题在下标为0的地方,获取文本)
                    title=new.find_all("div",class_="c-single-text-ellipsis")[0].text
                    #获取新闻的热度(热度在下标为0的地方,获取文本)
                    hot=new.find_all("div",class_="hot-index_1Bl1a")[0].text
                    #获取新闻的简介(简介在下标为0的地方,获取文本)
                    conent=new.find_all("div",class_="hot-desc_1m_jR small_Uvkd3 ellipsis_DupbZ")[0].text
                    #获取新闻的链接(通过第一个a标签,的href属性获取)
                    newUrl=new.find('a').attrs.get('href')
                    #获取要下载的图片链接的img标签(标签在下标为0的地方)
                    imgUrl=new.find_all("img")[0]
                    #获取要下载的图片链接(通过img的src属性获取)
                    imgUrl=imgUrl.attrs.get('src')
                    print('\n'+'标题:' + str(title) + '\n' + '热度:' + str(hot) + '\n' + '简介:' + str(conent) + '\n' + '新闻链接:' + str(newUrl) + '\n\n')
                    #请求图片
                    img=requests.get(url=imgUrl,headers=headers).content
                    #写出图片
                    with open('./百度热搜/' + str(title.strip()) + '.png', 'wb') as f:
                        f.write(img)
                    #写出文本
                    with open('./百度热搜/热搜文本.txt', 'a') as f:
                        f.write('\n'+'标题:' + str(title) + '\n' + '热度:' + str(hot) + '\n' + '简介:' + str(conent) + '\n' + '新闻链接:' + str(newUrl) + '\n\n')
                except:
                    continue;
            print('写出成功!')
            
    Hot_search()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    5.2 爬取图片壁纸

    注意:这里没有自动创建保存文件的文件夹,自行修改

    import requests
    from bs4 import BeautifulSoup
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40"
    }
    
    
    def indexUrl():
        indexUrls = ['http://www.netbian.com/meinv/index.htm']
        for i in range(2,4):
            indexUrls.append('http://www.netbian.com/meinv/index_'+str(i)+'.htm')
        #保存图片链接
        imgUrls=[]
        #当作图片名字
        imgName=1;
        for i in indexUrls:
            html=requests.get(url=i,headers=headers).content.decode('gbk')
    
            soup=BeautifulSoup(html,'html.parser')
            Alable=soup.find('div',class_='list').find_all('a')
            # print(Alable)
            for i in Alable:
                #获取图片地址的后半段地址
                iUrlP=i.attrs.get('href')
                #去除无效地址
                if 'http' in iUrlP:
                    continue;
                #将残缺的图片页面地址拼起来,形成完整图片页面地址
                imgUrlP= 'http://www.netbian.com' + iUrlP
                #向图片网页发起请求
                imgPage=requests.get(url=imgUrlP,headers=headers).content.decode('gbk')
                #将请求回来的源码转换为bs4
                soup=BeautifulSoup(imgPage,'html.parser')
                #获取图片链接地址
                imgUrl=soup.find_all('div',class_='pic')[0].find('img').attrs.get('src')
                #将图片地址保存到列表中(可以不存)
                imgUrls.append(imgUrl)
                #向图片地址发起请求
                imgget=requests.get(url=imgUrl,headers=headers).content;
                #下载图片
                with open('./壁纸/'+str(imgName)+'.jpg','wb') as f:
                    f.write(imgget)
                    imgName+=1;
        print('下载成功')
    
    indexUrl()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    5.3 豆瓣电影 Top 250

    结果保存到excel中的

    import requests;
    from bs4 import BeautifulSoup
    import xlwt
    
    # https://movie.douban.com/top250?start=25&filter=
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42'}
    
    
    #获取翻页页面连接
    def top250Urls():
        purls=[]
        urls=[]
        for i in range(0,25,25):
            url = 'https://movie.douban.com/top250?start='+str(i)+'&filter='
            purls.append(url)
        for purl in purls:
            html=requests.get(url=purl,headers=headers).content.decode('utf-8')
            soup=BeautifulSoup(html,'html.parser')
            movie_div = soup.find_all('div', class_='item')
            for movie in movie_div:
                movieUrl = movie.find_all("div", class_="pic")[0]
                movieUrl=movieUrl.find('a')
                movieUrl=movieUrl.attrs.get('href')
                urls.append(movieUrl)
        return urls,
    
    
    
    def Top250():
        moviesTop=[]
        urls=top250Urls()[0]
        for url in urls:
            html=requests.get(url=url,headers=headers).content.decode('utf-8')
            soup=BeautifulSoup(html,"html.parser")
            title=soup.find_all('span',property="v:itemreviewed")[0].text;
            move_info=soup.find_all('div',id="info")[0]
            performer=move_info.find_all('a',rel="v:starring")
            actors=[]
            for per in performer:
                actors.append(per.text)
            typeSpan=move_info.find_all('span',property="v:genre")
            types=[]
            for type in typeSpan:
                types.append(type.text)
            content = soup.find_all('span', property="v:summary")[0].text.strip('\n')
            movies={
                'title': title,
                'performer': actors,
                'type': types,
                'content': content
            }
            moviesTop.append(movies)
        WriteExcle(moviesTop)
            # return moviesTop;
    
    
    
    def WriteExcle(movies):
        try:
            #1、创建Workbook对象,就是创建Excel文件
            work_boot=xlwt.Workbook(encoding='utf-8');
            #2、创建sheet表单
            sheet=work_boot.add_sheet('formName') #formName为表单名称
            #3、写入Excel表头
            header=['电影名','演员','类型','电影简介'];
            for i in range(len(header)):
                sheet.write(0,i,header[i]);  #write(行,列,内容)
    
            #写入Excel内容
            for i in  range(len(movies)):
                sheet.write(i+1,0,movies[i]['title'])
                sheet.write(i+1, 1, movies[i]['performer'])
                sheet.write(i+1, 2, movies[i]['type'])
                sheet.write(i+1, 3, movies[i]['content'])
            #保存文件
            work_boot.save("小电影.xls")
            print('写入成功!')
        except:
            print('写入失败!')
    
    Top250()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    求求点赞、评论、收藏呀~

  • 相关阅读:
    什么是GNSS模拟器及其应用?
    DP7340——192KHz双声道输入24位AD 转换器
    mysql函数
    win 怎么设置默认浏览器
    【英雄哥六月集训】第 30天: 拓扑排序
    pytest:开始使用
    软件工程师和程序员到底有多大的区别?
    干货 | 一文搞定 pytest 自动化测试实战
    vue使用swiper(轮播图)-真实项目使用
    传输优化抽象
  • 原文地址:https://blog.csdn.net/qq_57340195/article/details/127396708