任務描述
本關任務: 本關任務:根據上個步驟中爬取的表格標簽,將表格中從第四行的單元格的文本顯示出來
行標簽和單元格標簽
表格中每行的數據信息被封裝在一個之間的結構中。 每列內容采用表示。 因此,如果要獲得其中的數據,需要首先找到標簽,并遍歷其中每個標簽,獲取其值 例如,表格的第四行對應的html代碼如下
函數
通過的(name)方法表格數據復制不過去,可以找到多個標簽,將多個標簽的內容返回為一個列表 lb=bg.("tr") 找到表格的所有tr標簽表格數據復制不過去,存入列表lb 若需要找每行下的所有td標簽,則需要對lb循環,對每個元素執行("td")
獲取標簽文本
在用find()方法找到特定的標簽后,想獲取里面的文本,可以用.text屬性或者.屬性。 如果該標簽下有多層次的子標簽,則必須使用text屬性。 對于該網頁的td標簽,如上圖所示,需要用text才能返回文本。并且需要用strip去掉換行符。 如果使用最內層的span標簽,則可以使用屬性。
編程要求
對于上述獲得的表格標簽的內容,爬取從第4行開始的文本, 顯示每行的地區名稱、總人口、城鎮人口、鄉村人口和城鎮化率 各項之間用空格隔開,包括最后一列后面也有空格 每個地區換一行
# 這是一個請求庫
import requests
# 將請求到的內容進行解析
from bs4 import BeautifulSoup
# 這是網址
url = "http://tjj.hunan.gov.cn/hntj/tjfx/tjgb/rkpc/
202105/t20210519_19079329.html"
# 調用請求庫進行網頁的請求,獲取網頁的內容
r=requests.get(url)
# 請求的時候防止亂碼的發生,一般是utf-8還有一個是b123啥的,忘了,utf-8比較常見。
r.encoding = 'utf-8'
# 對獲取到的內容進行解析,用的是text是獲取其內容,至于html.parser
是BeautifulSoup的參數的用法,不加上會報錯,詳細知道BeautifulSoup請查閱相關信息。
soup=BeautifulSoup(r.text,"html.parser")
# 獲取文本中的table標簽的內容
bg=soup.find('table')
#代碼開始
# 導入正則表達式的庫
import re
# 在table中獲取tr的內容
lb = bg.find_all('tr')
# 定義兩個列表,后面用于存儲
a = []
b = []
# 其實個人覺得下面的代碼有點多余了,當時自己也是按照自己的想法去做的,就沒有進行改了,
其實完全可以在lb的基礎上進行lb=lb[3:]的操作,為什么會有這一步,因為題目要求是從長沙市開始的,
長沙市在第四行因此需要這么做,如果不太了解的同學可以自行查看lb的結構,就知道答案了。
for i in lb:
a.append(i.find_all('td'))
a = a[3:]
# 這兩句是本人的簡單測試,可忽視
# print(len(a[0]))
# print(a[0][0])
'''
核心代碼講解部分:
for k, i in enumerate(a):
在這條語句中,k會記住坐標,而i會記住對應的內容,就好像['i lov you','but you do not love me']
;在這個列表中,k分別取值為0,1;i就會分別對應那兩句英文;的確,你真的不喜歡我,哈哈哈。
result = re.match(r'.*宋體">(.*?)<',str(j),re.S)
在這條語句中,是使用的正則表達式;re.match(1,2,3);在1的位置為正則表達式提取的要求,
2的位置是匹配的句子,3為滿足.*?不能進行換行而存在的需求;注意.*?和.*的用法,
一個是非貪婪匹配一個是貪婪匹配,詳解可以去查一下資料。在這里面會返回()中的內容;
如果要提取的要求很多的話,就要多個括號,group(1)是返回第一個括號,
注意這里是從1開始的,而不是0.
'''
for k,i in enumerate(a):
b.append([])
for j in i:
result = re.match(r'.*宋體">(.*?)<', str(j),re.S)
b[k].append(result.group(1))
# 對b中的內容進行提取,其實只是為了滿足題目要求罷了,否則完全可以進行pd.DataFrame操作,
直接轉為我們要的csv或者excel文件了
for i in b:
for j in i:
print(j,end=' ')
print()
#代碼結束
期間遇到的錯誤:
在re.match中報錯:
'NoneType' object has no attribute 'group'
運行直接報錯,也就是說正則表達式沒有匹配到這個字符串,返回結果為None,而我們又調用了group()方法導致了。為什么加入一個換行符就匹配不到了,是因為.*?遇到換行符就無法匹配了,因此在這里我們需要加上一個re.S,這個修飾符的作用是使.匹配包括換行符在內的所有字符,re.S在網頁匹配中經常用到,因為HTML節點經常會換行,加上它,就可以匹配節點之間的換行l.