1.首先用response=requests.get(url=url).content.decode(‘utf-8’)来获得网页源码。要先转为content或text(易乱码)格式才能被bs4解析
2.soup=BeautifulSoup(response.‘lxml’)解析源码,解析器为lxml(第三方),还有第一方解析器html.parser。
3.辨识html文件的标签和属性和所属文本内容。
用下面html文件(部分)演示。
<div class="song">
<p>李清照</p>
<p>王安石</p>
<p>苏轼</p>
<p>柳宗元</p>
<a href="http://www.song.com/" title="赵匡胤" target="_self">
<span>this is span</span>
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
<img src="http://www.baidu.com/meinv.jpg" alt="" />
</div>
<div class="tang">
<ul>
<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
</ul>
</div>
(1)这里面标签有:<div><p><a>(主标签)<span><ul><li>(子标签),标签以<标签名>开始,以</标签名>结束
(2)像<div class="song">这种是div标签,其属性为'song'。还有<a href="" class="du">这种,为<a>标签,其href属性为' '(没属性),其class属性为'du'
(3)'清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村'为<div class='tang'>标签(非直属)<ul>标签(非直属)<li>标签(非直属)<a>标签(直属)下的文本内容
4.定位需要的标签,有三种方法:(1)soup系:soup.标签名(2)find系:soup.find('标签名')与soup.find_all('标签名')(3)select系:select('id或class或标签')
(1)soup系:
print(soup)#打印解析出的源码
print(soup.a) #soup.标签名,这里是<a> ,返回的是html中第一次出现<a>标签下属的所有内容:
<a href="http://www.song.com/" target="_self" title="赵匡胤">
<span>this is span</span>
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
(2)find系:
print(soup.find('a')) #等同于print(soup.a),依然只给出第一次出现<a>标签下属的所有内容find('标签名'):等同于soup.标签名:
<a href="http://www.song.com/" target="_self" title="赵匡胤">
<span>this is span</span>
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
print(soup.find('div',class_='song').text)#在标签后加上其属性(class要加下划线变成class_,不然会与关键字class混淆),
这样就可以找到指定的div,而非第一个。
李清照
王安石
苏轼
柳宗元
this is span
宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱
总为浮云能蔽日,长安不见使人愁
print(soup.find_all('a'))#找到所有<a>标签并制成一个列表,返回一个列表(要得到文本信息要先注明第几个列表元素[n]再.text,不能直接用.text)
[<a href="http://www.song.com/" target="_self" title="赵匡胤"><span>this is span</span>宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>,
<a class="du" href="">总为浮云能蔽日,长安不见使人愁</a>,
<a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a>,
<a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a>,
<a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a>,
<a class="du" href="http://www.sina.com">杜甫</a>,
<a class="du" href="http://www.dudu.com">杜牧</a>,
<a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a>]
(3)select系:
print(soup.select('.tang'))#找到所有'id或属性或标签',返回的是一个列表。找标签直接写标签名,找属性要在属性值前加一个点。不能找属性,只能找属性值。
[<div class="tang">
<ul>
<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
<li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
<li><a class="du" href="http://www.sina.com">杜甫</a></li>
<li><a class="du" href="http://www.dudu.com">杜牧</a></li>
<li><b>杜小月</b></li>
<li><i>度蜜月</i></li>
<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
</ul>
</div>]
print(soup.select('.tang > ul a')[0]['href'])#select还可层级选择。层级选择器:soup.select('.tang > ul > li > a')表示的是一个层级一个层级的找到a,
soup.select('.tang > ul a'):表示从ul跨过li直接找到a,空格表示多个层级
返回值也是列表。
(4)获得文本值
加上.文本类型(有.text和.string),则只返回文本内容,而不再夹杂下属的标签头尾。
加上.text,可返回非直属文本内容。若加.string,只能返回直属文本内容。如soup.find('div',class_='song').text
(5)获得列表特定值
若返回值是列表,在后加[数字]可得到列表中第(数字+1)个值,如
print(soup.select('.tang > ul a')[0]) 运行结果:
<a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a>
(6)获得属性值
加一个[属性名]则获得属性的属性值,如
print(soup.select('.tang > ul a')[0]['href']) 运行结果:
http://www.baidu.com
(7)使用soup.select(),soup.find_all()所得列表,可以直接进行层级操作,如[<li><a c=1>hhh</a></li>, <li><a c=2>ddd</a></li>],
可以用print(li.a.string)或print(li.text)来打出hhh