解析庫BeautifulSoup4基本使用
一.安裝
pip install Beautifulsoup4
Beautiful Soup在解析時實際是依賴解析器的,它除了支持python標准庫中的HTML解析器外還支持第三方解析器如lxml等,推薦使用lxml.
安裝解析器: pip install lxml
創建beautifulsoup對象
soup=BeautifulSoup(html,'lxml')
html: 可以為 str, 也可以是 文件句柄fp
'lxml': 解析器, 需安裝lxml包
1.節點選擇器
直接調用節點的名稱就可以選擇節點元素,節點可以嵌套選擇, 返回的類型都是bs4.element.Tag對象
soup.head #獲取head標簽
soup.p.b #獲取p節點下的b節點
soup.p.string #獲取p標簽下的文本
當同級有多個相同節點時, 節點選擇器默認只選擇第一個
節點的屬性方法:
name屬性獲取節點的名稱:
soup.div.name
attrs屬性獲取節點屬,返回的結果可能是列表或字符串類型,取決於節點類型
soup.p.attrs #獲取p節點所有屬性
soup.p.attrs['class'] #獲取p節點class屬性
soup.p['class'] #直接獲取p節點class屬性 以字典的形式直接獲取
soup.p.get('class')
string屬性獲取節點元素包含的文本內容:
soup.p.string #獲取第一個p節點下的文本內容
contents屬性獲取節點的直接子節點,以列表的形式返回內容
soup.div.contents #直接子節點,bs4將換行也作為一個節點
children屬性獲取的也是節點的直接子節點,以生成器的類型返回
soup.div.children
descendants屬性獲取子孫節點,返回生成器
soup.div.descendants
parent屬性獲取父節點,parents獲取祖先節點,返回生成器
soup.b.parent
soup.b.parents
next_sibling屬性返回下一個兄弟節點,previous_sibling返回上一個兄弟節點,注意換行符也是一個節點,所以獲取兄弟節點是通常是字符串或者空白
soup.a.next_sibling
soup.a.previous_sibling
next_element和previous_element屬性獲取下一個被解析的對象,或者上一個
soup.a.next_element
soup.a.previous_element
next_elements和previous_elements迭代器向前或者后訪問文檔解析內容
soup.a.next_elements
soup.a.previous_elements
2.使用find_all
find_all(name,attrs,recursive,text,**kwargs):查詢所有符合條件的元素,其中的參數:
name表示可以查找所有名字為name的標簽(tag),也可以是過濾器,正則表達式,列表或者是True
attrs表示傳入的屬性,可以通過attrs參數以字典的形式指定如常用屬性id,attrs={'id':'123'},由於class屬性是python中的關鍵字,所有在查詢時需要在class后面加上下划線即class_='element',返回的結果是tag類型的列表
text參數用來匹配節點的文本,傳入的形式可以是字符串也可以是正則表達式對象
recursive表示,如果只想搜索直接子節點可以將參數設為false:recursive=Flase
limit參數,可以用來限制返回結果的數量,與SQL中的limit關鍵字類似
find_all(條件):查詢所有符合條件的元素
查找標簽名為 div 的所有元素
soup.find_all(name='div') # name代表標簽名,不是name屬性
soup.find_all('div') # 標簽查找
查找標簽名為 li 或 a 的所有元素
soup.find_all(name = ['li', 'a'])
查找 id 為 world 的所有元素
soup.find_all(id = 'world')
查找 class 為 active 的 所有元素
soup.find_all(class_='active') # class為python關鍵字,需加下划線
查找 a 標簽中,title 屬性為 hello 的所有元素
soup.find_all('a', title='hello') # 標簽 加屬性過濾
soup.find_all('a', title='hello', limit=2) # 限制輸出, limit屬性代表取前2個
查找 a 標簽中包含屬性 id='box', class='active' 的所有元素
soup.find_all('a',attrs={'id':'box','class':'active'}) # 多屬性過濾
查找文本中能匹配字符串 hello 的所有元素
soup.find_all(text=re.compile('Tillie')) # 使用正則過濾查找
其他方法:
find( name , attrs , recursive , text , **kwargs ):它返回的是單個元素,也就是第一個匹配的元素,類型依然是tag類型
參數同find_all()一樣
3. css選擇器
使用css選擇器語法查找元素
查找所有 a 標簽
soup.select('a')
查找 class = 'active' 的所有元素
soup.select('.active')
查找 id = 'box' 的元素
soup.select('#box')
查找 .active 的 所有后代 li 標簽
soup.select(.active li)
查找 li 標簽 的所有子元素 a
soup.select('li > a')
通過是否存在某個屬性來查找元素
soup.select('li[class]') # 查找帶有class屬性的所有 li 標簽
通過屬性的值來查找匹配
soup.select( 'li[class="active"]' ) # 查找帶有 class='hello' 的 所有 li 標簽
soup.select('li[class^="act"]') #匹配值的開頭
soup.select('li[class$="ve"]') #匹配值的結尾
soup.select('li[class*="tiv"]') #模糊匹配
獲取節點文本
soup.select('a')[0].get_text()
soup.select('a')[0].string #貌似僅有文本時有效, 嵌套了其他標簽時失效
