python 语言 beautifulsoup xpath

1.beautifui:美丽的

soup:汤

beautifulsoup:第三方库和xpath的作用是一样的都是用来解析HTML数据

相比之下xpath的速度会更快一点

xpath底层使用C语言来实现的

创建index.html

<!--! 提示  重要-->
<!--doc document 文本-->
<!--添加这句代码会变成标准的HTML模式否则会变成怪异模式-->
<!DOCTYPE html>
<!--&lt;!&ndash;html标签是根标签&ndash;&gt;  body是身体,head是头发布命令-->
<html lang="en">
<head>
    <!--<meta charset="UTF-8">-->
    <title>美食杰-美食|菜谱大全</title>
</head>
<body>
    <!--ul是列表-->
    <ul>
        <!--li单元格-->
        <!--li*3-->
        <li>啤酒</li>
        <li>饮料</li>
        <li>没茅台</li>
        <li>
            <!--a标签叫做超链接标签
            href为超链接属性 后面写跳转的地址-->
            <a class="bd net" id="baidu" href="https://www.baidu.com">百度</a>
        </li>
        <li><a class="shopping" href="https://www.taobao.com">淘宝</a>
        </li>
        <li><a id="jd" class="shopping" href="https://www.jd.com">京东</a>
        </li>
    </ul>
    <p class="frist">frist_people</p>
    <p class="frist" id="one">
        <span>hello world</span>
    </p>
    <p class="frist second" id="two">second_class</p>
    <div class="now">
        frist_div_element
        <p class="third">four</p>
        <a href="https://www.meishijie.net">meishijie</a>
    </div>
</body>
</html>
from bs4 import BeautifulSoup
# BeautifulSoup:里面需要两个参数
# 一个为open方法
# 一个为固定写法lxml  不用引包
# open方法里面需要两个参数
# 1.想要解析的数据
# 2.设置编码格式
bs=BeautifulSoup(open('index.html',encoding='utf-8'),'lxml')
print(bs)
print(type(bs))
# bs.title:获取网页当中的title标签
print(bs.title)
# 获取head标签及head标签内部的所有其他标签
print(bs.head)
# 获取网页当中的第一个a标签
print(bs.a)

# bs.xx获取所有xx当中的第一个XX以及第一个xx里面的内容
# document:文档
# name:获取当前内容的标签名 bs为一个整体,而不是某一个具体的标签
print(bs.name)
# 获取head标签的标签名
print(bs.head.name)
# 获取title标签的标签名
print(bs.title.name)
# attribute:属性
print(bs.html.attrs)
# 获取指定标签的所有属性
# 如果没有做特别处理bs.xx永远获取的是xx中第一个xx
print(bs.a.attrs)
print(bs.a['id'])
print(bs.a['href'])
# 类名(class)和id不一样id必须是唯一的
# class不是唯一的不同标签可以拥有同一个class
# 同一个标签也可以有多个class
print(bs.a['class'])
print(bs.html['lang'])
# 删除前
print(bs.a)
del bs.a['id']
# 删除后
print('*******************************')
print(bs.a)
# 获取指定标签的文本内容
print(bs.a.string)
# string 获取的文本指的是本标签的文本不包含子标签的文本
print('**************************')
print(bs.div.string)
# 遍历-------------------
# contents能够获取指定标签下面的所有内容
print(bs.head.contents)
print(bs.body.contents)
print(bs.div.contents[3])

# parent:父级
# 获取指定标签的父级标签和父级标签内部的所有标签
head=bs.title.parent
print(head)
# tag:标记/标签/
print(type(head))

res = bs.find_all('a')
print(res)
for value in res:
    print(value)
# id是唯一的通过id来找只能找到一个  所以用find
# class不是唯一的 通过class来找 可能知道多个
print(bs.find(id="jd"))
print(bs.find_all(class_='shopping'))
# 找到所有符合条件当中的第一个
print(bs.find(class_="shopping"))
print(bs.find_all(id="jd"))

# select------------------------
# 选择指定的标签/
print(bs.select('title'))
# 当选择的对象有多个的时候,将获所有的对象
print(bs.select('a'))
# .表示类名  #表示id
print(bs.select('.frist'))
print(bs.select('#jd'))
# print(bs.select('href'))这种写法是不行的
print(bs.select('p.frist'))
# 找到一个类名为now的标签
print(bs.select('div.now'))

beautifulsoup练习

# 文件处理的高级模块,功能强大  比os更加强大
import shutil ,os
from bs4 import BeautifulSoup
# 可以用来下载图片
from urllib.request import Request,urlopen,urlretrieve
class image_download(object):
    def __init__(self):
        self.base_url='http://www.ivsky.com/'
        self.current_page=1
    def stat_download(self):
        # 判断是否存在指定文件夹  如果存在则删除
        if os.path.exists('image'):
            # rm remove删除 tree:树
            # 删除树状结构的文件夹
            # True 忽略错误信息
            shutil.rmtree('image',True)
        else:
            os.mkdir('image')
        # 如果要对某个文件夹内部进行操作首先先进入此文件夹内部
            os.chdir('image')
            frist_page='tupian/index_1.html'
            self.get_page_code_with_url(frist_page)
    def get_page_code_with_url(self,url):
        full_url=self.base_url+url
        # print(full_url)
        headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0'
        }
        request=Request(full_url,headers=headers)
        try:
            response=urlopen(request)
            code=response.read().decode()
        except Exception as e:
            print('请求数据失败',e)
        else:

            self.get_data_with_code(code)

    def get_data_with_code(self,code):
        print('正在下载第{}页...'.format(self.current_page))
        soup=BeautifulSoup(code,'lxml')
        page_name='{}.page'.format(self.current_page)
        os.mkdir(page_name)
        # 进入1.page文件
        os.chdir(page_name)
        image_list=soup.select('ul.ali a img')
        print(image_list)
        for image in image_list:
            image_src=image.get('src')
            image_alt=image.get('alt')
            image_alt=image_alt.split('(')[0]+'.jpg'
            # print(image_alt)
            # print(image_src)
            urlretrieve(image_src,image_alt)
            # 将光标移到父级文件及外面
            os.chdir(os.path.pardir)
            self.current_page+=1
            # 告诉下一页当前是哪一页
            self.get_next_page(code)
    def get_next_page(self,code):
        # 将当前页代码转化成soup对象进行解析
        soup=BeautifulSoup(code,'lxml')
        # 选择当前页中类名为page-next的a标签
        # 从所有的符合要求标签中找到第一个
        next_page=soup.select('a.page-next')[0]
        # 获取该标签的href属性
        url=next_page.get('href')
        # print(url)
        self.get_page_code_with_url(url)
download=image_download()
download.stat_download()
import requests
from bs4 import BeautifulSoup


url='http://news.baidu.com/'
response=requests.get(url).content
print(response)
bs4_soup=BeautifulSoup(response,'lxml')
print(bs4_soup)
new_list=bs4_soup.select('ul.focuslistnews li a')
print('******************')
print(new_list)
for new in new_list:
    href=new.get('href')
    text=new.get_text()
    print('新闻'+text+'链接:'+href)

2.xpath

# e  element:元素,节点,标签
# tree:树   etree:标签树
from lxml import etree

html_str="""
<a href='https://www.baidu.com'>
百度一下,你就知道
</a>

"""
# 将字符串转化成标签
# 该方法会检测字符串内容是否为标签样式但是不能检测出内容是否为真的标签
result=etree.fromstring(html_str)
print(result)
# parse:解析
html=etree.parse('index.html')
print(type(html))
# 找到网页内所有的标签
a = html.xpath('//a')
print(a)
# 获取指定标签的类型
result=html.xpath('//a/@class')
print(result)
# 找到所有标签的id
result=html.xpath('//a/@id')
print(result)
# 找到所有标签的超链接属性
result=html.xpath('//a/@href')
print(result)

# 找到指定的文本内容

result=html.xpath('//a/text()')
print(result)
# 如果找某一个标签的文本 而这个标签下面还要其他的标签
# 那么只找这个标签文本 子标签的文本不找
result=html.xpath('//div/text()')
print(result)
# //text()找到本标签以及所有子标签的文本
result=html.xpath('//div//text()')
print(result)
# 获取指定id名字的标签文本
result=html.xpath('//ul/li/a[@id="jd"]/text()')
print(result[0])
# last()获取最后一个标签
result=html.xpath('//ul/li[last()]')[0]
print(result)
# 获取指定类名的标签的文本
result=html.xpath('//a[@class="shopping"]/text()')
print(result)
# contains:包含指定属性
result=html.xpath('//div[@class="now"]/p[contains(@class,"third")]/text()')
print(result)


# 找到所有的ul标签
# 找到所有的ul标签中所有的a标签
# 获取a标签文本和所有的a标签的子标签的文本
result=html.xpath('//ul//a//text()')
print(result)

xpath图片下载

import os
from urllib.request import urlretrieve
from lxml import etree
import requests
import shutil


if os.path.exists('images'):
    shutil.rmtree('images')
os.mkdir('images')
os.chdir('images')
current_page=1
def get_image_with_code(url):

    global current_page
    # 总结:xpath和bs4和正则的区别
    # 数据方式的区别
    # request
    # response=urlopen().read().decode()
    # response=requests.get().content
    response=requests.get(url).content
    # print(response)
    # Element:元素 ;节点;标签
    code=etree.HTML(response)
    # print(code)
    img_list=code.xpath('//div[@class="il_img"]/a/img')
    print(img_list)
    print('正在下载第{}页'.format(current_page))
    # 对应页面的文件夹
    os.mkdir('page{}'.format(current_page))
    # 移动光标
    os.chdir('page{}'.format(current_page))
    for img in img_list:
        # img_src=img.xpath('@src')[0]
        img_src=img.get('src')
        img_alt=img.get('alt')
        # print(img_alt)
        # print(img_src)
        urlretrieve(img_src,img_alt+'.jpg')
        #局部变量  声明的作用是告诉程序该变量是声明类型的变量
    current_page+=1
    # 移出光标/
    os.chdir(os.path.pardir)
    # 如果还有下一页则返回[Elemment a ip]
    # 如果没有下一页则返回[]
    next_page_url=code.xpath('//a[@class="page-next"]')
    print(next_page_url)
    if len(next_page_url)==0:
        print('已经找到最后一页')
        return
    href =next_page_url[0].get('href')
    print(href)
    full_url='http://www.ivsky.com/'+href
    get_image_with_code(full_url)

get_image_with_code('http://www.ivsky.com/tupian/meishishijie/')
#
# 爬虫流程:
# 1.拼接url
# 2.获取user-agent,设置代理ip
# 3.请求url:①urlopen②requests
# 4.获取响应(response  response.read() response.content response.text)
#     获取cookie
# 5.获取源码中指定数据(re, xpath ,bs4)
# 6.更新数据  (正则,strip)
# 7.保存(文件读写操作(fs),sqlite3,xlwt)
import xlwt
import requests
from lxml import etree
from fake_useragent import UserAgent


class DBMoive(object):
    def __init__(self):
        self.base_url='https://movie.douban.com/top250'
        self.current_page=1
        self.headers=UserAgent()
        self.workBook=None
        self.sheet=None
        #记录当前是第几行
        self.record=1
    def start_load_dbmoive(self):
        self.get_excel()
        #第一次调用该方法url的值不用传
        self.get_code_with_url()
        self.wookbook.save('豆瓣top250.xls')
    def get_excel(self):
        self.wookbook=xlwt.Workbook(encoding='utf-8')
        self.sheet=self.wookbook.add_sheet('电影排行榜')
        self.sheet.write(0,0,'排名')
        self.sheet.write(0, 1, '影片')
        self.sheet.write(0, 2, '导演和演员')
        self.sheet.write(0, 3, '评分')
        self.sheet.write(0, 4, '评论人次')
    def get_code_with_url(self,url=''):
        # 随机获取一个用户标识
        headers={
            'User-Agnet':self.headers.random
        }
        full_url=self.base_url+url
        response=requests.get(full_url,headers=headers).text
        # print(response)

        item_div=response.xpath('//div[@class="item"]')
        for tag in item_div:
            # .从当前节点开始取
            # ..从父节点开始取
            rank=tag.xpath('.//em[@class=""]/text()')[0]
            print(rank)
            movie_name = tag.xpath('.//div[@class="hd"]/a/span/text()')
            # print(movie_name)
            name = ''
            for movie in movie_name:
                name += movie
            # print(name)
            creater = tag.xpath('.//div[@class="bd"]/p[@class=""]/text()')[0]
            creater = creater.strip('\n').replace(' ', '')
            # print(creater)
            start = tag.xpath('.//span[@class="rating_num"]/text()')[0]
            # print(start)
            comment_num = tag.xpath('.//div[@class="star"]/span[last()]/text()')[0]
            comment_num = comment_num[0:-3]
            print(comment_num)
            self.sheet.write(self.record,0,rank)
            self.sheet.write(self.record, 1, name)
            self.sheet.write(self.record, 2, creater)
            self.sheet.write(self.record, 3, start)
            self.sheet.write(self.record, 4, comment_num)
            self.record+=1
        self.get_code_next_page(code)
    def get_code_next_page(self,code):
        next_url=code.xpath('//span[@class="next"]/a/@href')
        if len(next_url)==0:
            print('已经是最后一页了')
            return
        self.get_code_with_url(next_url[0])


movie=DBMoive()

movie.start_load_dbmoive()

猜你喜欢

转载自blog.csdn.net/crq_zcbk/article/details/81412095