了解更多关注微信公众号“木下学Python”吧~
1.安装库并导入
安装这个库是pip install bs4,不是BeautifulSoup,导入为‘from bs4 import BeautifulSoup’
2.适用情况
例如要爬取简书网热评,每一篇文章都对应有消息,当有些有打赏,有些没有,这样匹配出来的数据就会对应不上,就如 1号没有打赏,但2号有打赏,那2号的打赏就会匹配给1号。只有当要爬取的每一组数据都有对应的值得时候,才可用bs4
3.爬取网站代码结构:
#访问
res = request.get(url,headers = headers,timeout = 10)
soup = Beautiful(res.text,'lxml')
#爬取
names = soup.select('copy selector内容')
apps = soup.select('copy selector内容')
copy selector内容最好写全路径
4.select(‘html的copy select’)方法
li:nth-of-type(1)为1条信息,li为多条信息
有时候爬取不全可能死里面路径的问题,适当修改一下,删除一些路径,如:
tops = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num > strong')
tops = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num)
这里只是一个例子,原来没删除我的结果只有3条,删除后就全部都有了
NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type
nth-child 改为 nth-of-type(1)
li:nth-of-type(1)为1条信息,li为多条信息
5.get_text()
提取select返回列表中标签中的信息
6.find() 与 find_all() 用法
前者返回一个,后者返回所有的数据的列表!
find(name,attrs,recursive,text,**wargs)
find.attrs 获得标签所有属性
123
-
Area
要获得
ul = html.find('ul',attrs={'class':'name'})
li = ul.find('li').text
例如:
要提取其中的数据,可用 .find_all('div',class_="house-title").a.text.strip() 得到,.text 可换成 .string
注意:class 是 class_;其中的 .a 是指 标签
例如:
2室1厅|
95m²|
低层(共6层)|
2009年建造刘亚男
提取 2室1厅: .find('div',class_="details-item").span.text 或者 .find('div',class_="details-item").contents[1].text
提取 95m²:.find('div',class_="details-item").contents[3].text
提取 低层(共6层):.find('div',class_="details-item").contents[5].text
7.findALL 和 find_all
通过get函数获得标签的属性:
soup=BeautifulSoup(html,'html.parser')
pid = soup.findAll('a',{'class':'sister'})
for i in pid:
print i.get('href') #对每项使用get函数取得tag属性值
http://example.com/elsie
http://example.com/lacie
http://example.com/tillie
对其他的标签也是同样可用的,并且输出的结果为文档中第一个匹配的对象,如果要搜索其他的标签需要使用 find findAll函 数。
BeautifulSoup提供了强大的搜索函数find 和findall,这里的两个方法(findAll和 find)仅对Tag对象以及,顶层剖析对象有效。
findAll(name, attrs, recursive, text, limit, keyword)
attrs 是一个若干属性和对应属性值,class 属性对应 name,也可以对应name,以及ass,{'class':{'name','ass'}}
递归参数recursive是一个布尔变量,默认是True,抓取文档标签结构里多少层的信息·,查找name标签下的所有子标签;
设为False,只查找一级标签
文本参数text,,用标签的内容文本去匹配,而不是用标签的属性,假如我们先查找网页内容中包含‘pan’内容的标签数量,可以这样写 html.findALL(text='pan')
范围限制参数limit,对网页中获取的前x项干兴趣,可以设置
关键词参数keyword,可以选择那些指定属性的标签,html。findALL(id='text')
for link in soup.find_all('a'): #soup.find_all返回的为列表
print(link.get('href'))
# http://example.com/elsie
# http://example.com/lacie
# http://example.com/tillie
findAll也可以使用标签的属性搜索标签,寻找 id=”secondpara”的 p 标记,返回一个结果集:
pid=soup.findAll('p',id='hehe') #通过tag的id属性搜索标签
print pid
[The Dormouse's story
]
pid = soup.findAll('p',{'id':'hehe'}) #通过字典的形式搜索标签内容,返回的为一个列表[]
print pid
[The Dormouse's story
]
例如去取url:
for link in html.find_all('a'):
#if 'href' in link.attrs:
print(link.get('href'))
for link in html.findAll('a'):
if 'href' in link.attrs:
print(link.attrs['href'])
8.提取 url 标签看到的属性和趴下来的属性不一样
再浏览器中看到的 url 的属性为 src
爬取下来的实际 url 的属性 为 source-data-lazy-img
按照浏览器中看到的属性 src 爬 url 没有结果,经过断点调试,发现实际属性和看到的不一样
9..prettify()
打印 html 代码
10.判断是否是标签
if isinstance(tr,bs4.element.Tag): #过滤非标签
tds = tr('td') #对 tr 子标签中的 td 标签做查询,tds 为列表
university_list.append([tds[0].string,tds[1].string,tds[2].string]) #获得前三个文本
11.link.attrs['href'].startswith('/')
获得 link 标签的所有属性中的 href 属性,判断是否是以 / 开头