Beautiful Soup库是解析、遍历、维护“标签树”的功能库。
1 url = "http://desk.zol.com.cn/" 2 request = requests.get(url) 3 html = request.content 4 soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
一.解析器:
1.BeautifulSoup(markup, "html.parser")
2.BeautifulSoup(markup, "lxml")
3.BeautifulSoup(markup, "xml")
4.BeautifulSoup(markup, "html5lib")
二.Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
Tag , NavigableString , BeautifulSoup , Comment .
1.Tag 标签:
任何存在于HTML语法中的标签都可以用soup.<tag>访问获得。
当HTML文档中存在多个相同<tag>对应内容时,soup.<tag>返回第一个。
例如,
soup.a ---> 返回<a>标签的内容;
soup.a.name --> 返回<a>标签的名字;
soup.a.parent.name --> 返回<a>标签上一层的标签名字;
soup.a.parent.parent.name
soup.a.attrs --> 返回<a>标签的所有属性;
soup.a.attrs['class'] --> 返回<a>标签的class属性;
soup.a.string --> 返回<a>标签中的非属性内容(也就是<>...</>中的内容); 只能获取一个!
soup.get_text() --> 获取所有内容;获取标签下所有的文字内容! soup.get_text(" ", strip=True)可以这样去除空白行;
soup.strings --> 如果tag中包含多个字符串,可以使用 .strings 来循环获取;
soup.stripped_strings --> soup.strings输出的字符串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白内容;
三.基于bs4库的HTML内容遍历方法
soup.contents
soup.a.contents --> 将<a>标签所有子节点存入列表;
soup.a.children --> 与contents类似,但用于循环遍历子节点;
soup.a.descendants --> 用于循环遍历子孙节点;
注意:BeautifulSoup 对象本身一定会包含子节点,也就是说<html>标签也是 BeautifulSoup 对象的子节点!
soup.prettify() --> 让HTML内容更加“友好”的显示,prettify()为HTML文本<>及其内容增加更加'
'。
四.信息提取
soup.find_all(name,attrs,recursive,string,**kwargs)
name:对标签名称的检索;
attrs:对标签属性值的检索;
recursive:是否对子孙全部检索,默认为True;
string: <>...</>中字符串区域的检索。
例如,soup.find_all('a')
soup.find_all(['a','b'])
注意:find_all()中可以使用正则表达式来检索特定内容!
soup.find_all(re.compile(r'^a'))
例一:
1 import requests 2 from bs4 import BeautifulSoup 3 4 request = requests.get("http://www.163hnzk.com/index_pc.php") 5 html = request.content 6 soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8") 7 spans = soup.find_all(name='span', attrs={'class': 'newstitle'}) 8 9 hrefs = [] 10 for href in spans: 11 hrefs.append(href.a.attrs['href']) 12 13 for url in hrefs: 14 # 因为url含有特殊字符不能创建文件,所以split去掉特殊字符 15 with open("E:\%s" % url.split('?')[1], "wb") as f: 16 # 'wb'所以要用content,‘w’用text 17 f.write(requests.get("http://www.163hnzk.com/"+url).content)
例二:
1 import requests 2 from bs4 import BeautifulSoup 3 import pandas as pd 4 5 #request函数用来解析页面,获取所需内容 6 def request(number): 7 header={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'} 8 html = requests.get("https://hr.tencent.com/position.php?&start="+str(number), headers=header).text 9 soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8') 10 evens = soup.find_all(name='tr', attrs='even') 11 odds = soup.find_all(name='tr', attrs='odd') 12 trs = evens+odds 13 for tr in trs: 14 dct={} 15 dct["职位名称"]=tr.select('td a')[0].get_text() 16 dct["职位类别"]=tr.select('td')[1].get_text() 17 dct["招聘人数"]=tr.select('td')[2].get_text() 18 dct["工作地点"]=tr.select('td')[3].get_text() 19 dct["发布时间"]=tr.select('td')[4].get_text() 20 dct["链接地址"]='http://hr.tencent.com/'+tr.select('td a')[0].attrs['href'] 21 lst.append(dct) 22 23 #使用pandas保存为excel文件 24 def read_write(lst): 26 with open(r'E:zhaopin.csv', 'w', encoding='utf-8') as f: 27 #字典列表可作为输入数据传递以创建数据帧(DataFrame),字典键默认为列名。 28 datafram = pd.DataFrame(lst) 29 datafram.to_csv(r'E:zhaopin.csv', index=False) 30 31 if __name__=="__main__": 32 number = 0 33 #lst用来保存抓取的信息 34 lst=[] 35 while True: 36 #只抓取前5页的内容 37 if number < 50: 38 request(number) 39 number = number+10 40 else: 41 break 42 read_write(lst)
结果:
传送门--Beautifulsoup官方文档