BeautifulSoup

 

 

from bs4 import BeautifulSoup
import bs4, requests, os

#Beautiful Soup 4.4.0官网  https://beautifulsoup.readthedocs.io/zh_CN/latest/
#使用BeautifulSoup模块来从HTML文本中提取我们想要的数据, BeautifulSoup 有多个版本,我们使用BeautifulSoup4
#lxml,这是一个解析器,BeautifulSoup可以使用它来解析HTML,然后提取内容
#如果不安装lxml,则BeautifulSoup会使用Python内置的解析器对文档进行解析。之所以使用lxml,是因为它速度快。
 
#Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象。
#所有对象可以归纳为4种类型: BeautifulSoup, Tag , NavigableString, Comment 
#Tag:html中的标签  提取标签的名字:tag.name 提取标签的属性:tag['attribute']
#NavigableString:就是标签中的文本内容(不包含标签)。获取方式如下:tag.string
#Comment: HTML和XML中的注释。

#代理用户名密码,如果不需要可以去掉这个参数
proxy_dict = {
        "http": "http://username:123456@openproxy.huawei.com:8080"
    }

def main(): 
    testBeautifulSoup()
    testComment()
    testGrabPic()
    
def testBeautifulSoup():
    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <p class="story">...</p>
    """
    #BeautifulSoup对象表示一个文档的全部内容
    soup = BeautifulSoup(html_doc, 'lxml')  #声明BeautifulSoup对象
    #find()与find_all()类似都是搜索文档树 
    #只不过find()只返回找到的第一个值,返回类型是bs4.element.Tag。
    #find_all()返回<class 'bs4.element.ResultSet'>类似查询数据库查询到的结果集合
    # 最常用的当然是find()和find_all()啦,当然还有其他的。比如find_parent() 和 find_parents()、 
    # find_next_sibling() 和 find_next_siblings() 、find_all_next() 和 find_next()、
    # find_all_previous() 和 find_previous() 
    # find(name , attrs , recursive , string , **kwargs )    
    # find_all(name , attrs , recursive , string , **kwargs )
    # name 参数:可以查找所有名字为 name的tag。
    # attr 参数:就是tag里的属性。
    # string 参数:搜索文档中字符串的内容。
    # recursive 参数: 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点。如果只想搜索tag的直接子节点,可以使用参数 recursive=False 。
    # 搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。返回值类型是bs4.element.ResultSet。
    findResult = soup.find('p')  #使用find方法查到第一个p标签 
    print("find's return type is ", type(findResult))  #<class 'bs4.element.Tag'>
    print("find's content is", findResult)  #"<p class="title"><b>The Dormouse's story</b></p>"
    print("find's Tag Name is ", findResult.name)  #输出标签的名字  "p"
    print("find's Attribute(class) is ", findResult['class'])  #输出标签的class属性值 ['title']
    #NavigableString就是标签中的文本内容(不包含标签)
    print('NavigableString is:', findResult.string)

    #1.节点和标签名
    #可以使用子节点、父节点、 及标签名的方式遍历:
    print(soup.head) #"<head><title>The Dormouse's story</title></head>"
    #查找第一个p标签
    print(soup.p)  #"<p class="title"><b>The Dormouse's story</b></p>"
    print(soup.find_all("title"))

def testComment():
    print("-----testComment()--------")
    markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
    soup = BeautifulSoup(markup, "lxml")
    #comment其实就是HTML和XML中的注释
    comment = soup.b.string
    print(comment)  #"Hey, buddy. Want to buy a used parser?"
    print(type(comment)) #<class 'bs4.element.Comment'>
    if type(comment) == bs4.element.Comment:
        print('该字符是注释')
    else:
        print('该字符不是注释')        

#爬虫抓取这个网址指定的图片存储在本地
def testGrabPic():
    url = "http://www.ivsky.com/bizhi/dianying_t4566/"
    response = requests.get(url, proxies=proxy_dict)
    print(response.text)
    soup = BeautifulSoup(response.text, 'html.parser')
    allImgContent = soup.find('ul', class_="il")
    print(type(allImgContent)) # <class 'bs4.element.Tag'>
    print(allImgContent)
    print("-------------")
    allImg = allImgContent.find_all("img")
    print(type(allImg)) # <class 'bs4.element.ResultSet'>
    print(allImg)
    root='D:/pic/'
    try:
        if not os.path.exists(root):
            os.mkdir(root)
    except:
        print("mkdir fail")
          
    for img in allImg: 
        print(type(img)) # <class 'bs4.element.Tag'>
        print(img)
        src = img['src']        
        print("src:", src)
        path = root + src.split("/")[-1] 
        print(path)
        
        try:
            if not os.path.exists(path):
                r = requests.get(src, proxies=proxy_dict)
                with open(path, "wb") as fp:
                    fp.write(r.content)
                    fp.close()
                    print("Save OK")
            else:
                print("File has existed")
        except:
            print("fail to reptile!")   
            
if __name__ == '__main__':
    main()   

find's return type is <class 'bs4.element.Tag'>
find's content is <p class="title"><b>The Dormouse's story</b></p>
find's Tag Name is p
find's Attribute(class) is ['title']
NavigableString is: The Dormouse's story
<head><title>The Dormouse's story</title></head>
<p class="title"><b>The Dormouse's story</b></p>
[<title>The Dormouse's story</title>]
-----testComment()--------
Hey, buddy. Want to buy a used parser?
<class 'bs4.element.Comment'>
该字符是注释

.........................

后面省略

 

posted @ 2019-01-22 16:51  牧 天  阅读(272)  评论(0)    收藏  举报