Beautiful Soup库笔记

这个库的使用常规是两行代码

from bs4 import BeautifulSoup

soup = BeautifulSoup("html","html.parser") #前面那个就是打开html界面,后面是解释器,这个自带的够用,也可以用别的

运行完了之后,这个soup应该就可以调取网页上的所有内容,把那个网页看成是用<body><p>,这些东西组成的网页,好理解多了,然后就可以用这个soup去调用这些body,p什么的。

soup.p.name      #用.name的方式获得名字

soup.p.parent     #获得父母标签

print(soup.prettify())     #prettify函数可以为网页的那一大批标签名字什么的增加换行符,每一个标签都分行显示,看起来更清晰。

pritn(soup.a.prettify())  #也可以单独对某一个标签做换行

requests+BeautifulSoup库实战:

1.定向爬虫就是只爬取一个url链接,扩展爬虫是从一个url扩展到更多的url,首先去了解定向爬虫。

2.request返回了r,r.text是网页的代码展示,<p><body>这一系列的东西,把这些东西用BeautifulSoup

3.用这么简单的办法从网页里面爬东西,那要求这东西就放在网页的代码里面,如果使用JavaScript动态生成的,那就没办法了。在网页上点右键,看网页源代码,然后搜一下文字在不在里面。

requests.get和BeautifulSoup处理的不同:

其实单从返回来看,差别不是很大,打印出来都是尖括号后面有一些乱码字符的样子。

BeautifulSoup库的使用方法是传入一段文档,然后返回文档里的对象。get得到的东西,虽然看着也是那么回事,可你没法调用啊,把它变成对象才能调用。

提取大学排名的步骤:

1.把网页信息爬下来

2.把信息存到合适的数据结构里

3.把数据结构展示出来

import requests
from bs4 import BeautifulSoup
import bs4

def GeTHTML(url):
    try:
        r = requests.get(url,timeout =30)
        r.raise_for_status()                                    
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

def fillList(ulist,html):
    soup = BeautifulSoup(html,"html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr,bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string,tds[10].string,tds[2].string])

def printList(ulist,num):#python比较倾向于用format方法格式化输出
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u = ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2]))

uinfo =[]
url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html"
html = GeTHTML(url)
fillList(uinfo,html)
printList(uinfo,10)

1.soup的查找:

在soup=BeautifulSoup()之后,这里应该是数据结构上的变化,soup可以用title,name这些东西去检索了。

在源代码的文件里面,有什么东西,比如<title><p><a>,这些都可以直接用soup去索引,soup.a, soup,title , soup.p这样

这几个每一条返回的都是一行,如果页面里有很多的<a>,那用soup.a只返回第一个,要想把所有的都返回,就要用find_all语句

soup.find_all('a')       #这个find_all就是用于全局查找的

如果要细致的需求

soup.find(id = "link1")

2.isinstance用来判断两个是否是同一个类型的

isisntance(A(),B)               ,判断A和B是否是同一个类型

另外的就是type, type(A())==B

3.dict字典的使用:

(1)定义d={'a':1, 'b':2, 'c':3}

(2)调用d['a']           #调用dict的时候,跟数组的调用方法很类似,都是中括号,只不过里面不是1234,用的是字符的索引。

(3)>>>d        >>>{'a':1, 'b':2, 'c':3}            #如果输入d就把赋值的那一些给弹出来了

(4)d.pop('a')          #删除用的是pop,输出被弹出的东西,然后删掉

dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)

4.第二个函数里面的查找,顺序应该这样的,首先在源代码里面找清华大学,找到清华大学属于的那个<td>,然后找离这个最近的<tr>,一定要找到离要查对象最近的,也就是他的直属父亲。

BeautifulSoup返回对象存在的形式,是数组。tr下面,把那些尖括号,每一次尖括号直到这一次的结束,都变成了数组的一个元素。如果不是直属父亲,那遍历这个数组,在数组里面的子数组里面,肯定遍历不到。

输入print(tr('td'))

>>>[<td>298</td>, <td><div align="left">江西农业大学</div></td>, <td>江西省</td>]

tr('td')[0]             >>><td>298</td>

上面代码里的.string,应该就是把这个<td>给跳过了,只输出里面的字符串部分,直接输出什么都出来了

5.输出print的格式化format

print("\t"),这个字符串的\t是Tab的意思

print("\n"),回车

format的格式化输出,格式是这样的:

print("{:^10}    {:^10}    {:^10}".format('a','b','c'))

format可以认为是一个插入结构,前面有一个字符串"xxxx".format(),format的括号里面写的就是原来print函数原来应该打印的。那个xxxx就是要对format括号里的东西做的处理。这里只学一个处理,{:^10},^是居中,<居左,>居右,后面就是一共占几位。

最后的排版问题

def printList(ulist,num):                   
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称","总分" , chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0],u[1],u[2], chr(12288)))

把输出的这个函数给改掉

format那一行,之前和之后都改掉,之前的那一段由于上下,也就是第一行和下面所有行都用得上,所以单独拿出来做一个变量。

tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"

括号里的第一个数字,是对应输出format后面的第几个元素,第二个^表示的是居中,这个^后面的10表示的是填充。

中英文输出的问题在于中英文的空格符号占的大小不一样,在中英文混合输出的时候,把空格改了就好很多

猜你喜欢

转载自blog.csdn.net/sinat_38640606/article/details/82863491