最近在學(xué)習(xí)py,整理一下自己的學(xué)習(xí)記錄囊颅,算是備忘了吕世。
py新手艺演,僅供新手小伙伴們學(xué)習(xí)
1.BeautifulSoup中文文檔地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#extract
概覽
我們平常爬蟲了解這幾個類就可以了
上面這個圖 我們最常用用到的就是Tag
和NavigableString
我們指導(dǎo)html是標(biāo)記語言实牡,我們想爬的數(shù)據(jù)都是被格式各樣的標(biāo)簽嵌套的。
像<head>數(shù)據(jù)</head>
而BeautifulSoup 簡單的來說就是找標(biāo)簽取數(shù)據(jù)悴务,總體來說學(xué)習(xí)成本特別低睹限,容易上手。
我們來一步一分分析 對象的創(chuàng)建 以及 返回的類型
1.BeautifulSoup 的初始化
soup = BeautifulSoup(content,'lxml')
soup 是一個BeautifulSoup類型讯檐,從上面的繼承關(guān)系看其實就是一個Tag類型羡疗。一個大Tag包含著無數(shù)的小Tag
2.初步定位tag
tag = soup.find('table')
返回的是一個也是tag類型
tags = soup.find_all('table')
返回的是一個ResultSet 其實就是一個list類型的子類,在bs4.element
文件中有說明
3.具體定位tag
當(dāng)我們獲取大體的Tag對象時别洪,我們?nèi)绻氆@取其中子Tag的數(shù)據(jù)
這里要分2種情況
一 叨恨。。標(biāo)記有屬性標(biāo)記
直接再通過第二步的方法繼續(xù)獲取
二 挖垛。痒钝。沒有屬性標(biāo)記 如<td></td>
str_list = tag.contents
返回一個list對象
str_list_iterator = tag.children
返回一個list_iterator
4.獲取數(shù)據(jù)
首先要說一點 上面第三步說的獲取具體的tag,其實通過contents和children獲取的不只是Tag對象,還有NavigableString對象痢毒。這點一定要清楚送矩。
直接通過string
屬性來獲取就可以了
實戰(zhàn)
爬取ip代理網(wǎng)站(2種不同的類型),獲取代理ip哪替。
1.西刺免費代理IPhttp://www.xicidaili.com/nn
網(wǎng)頁源代碼 我就不貼在這邊了
源代碼 大家自己另開的網(wǎng)頁自己看下
通過分析源代碼栋荸,我們很清楚的發(fā)現(xiàn)我們數(shù)據(jù)實在table
標(biāo)簽內(nèi)(而且頁面只有一個table標(biāo)簽)
1.初始化
soup = BeautifulSoup(res.content,'lxml')
2.定位大體的Tag(這一步可以省略)
table_tag = soup.find('table')
3.定位具體的Tag
tr_list = table_tag.find_all('tr')
4.得到數(shù)據(jù)
for index,tr_tag in enumerate(tr_list):
if index > 1:
td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
print('ip: ' + td_list[1].string + ':' + td_list[2].string)
我們分析源碼可以發(fā)現(xiàn) 第1,2個tr 是表頭,不包含我們想要的數(shù)據(jù)凭舶,可以跳過晌块。
在contents獲取或有子節(jié)點的時候,我們會發(fā)現(xiàn)返回的不只有tag對象還有‘\n’字符的None類型帅霜。所以我們要用filter
過濾這些噪音數(shù)據(jù)匆背。
在過濾之后,我們可以清楚的看到 第二個tag對象時ip地址身冀,第二個是端口號钝尸。
import requests
from bs4 import BeautifulSoup
res = requests.get('http://www.xicidaili.com/nn',headers = { 'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20' })
soup = BeautifulSoup(res.content,'lxml')
table_tag = soup.find('table')
tr_list = table_tag.find_all('tr')
for index,tr_tag in enumerate(tr_list):
if index > 1:
td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
print('ip: ' + td_list[1].string + ':' + td_list[2].string)
這里在請求數(shù)據(jù)的是時候,因為西刺有防爬處理搂根。我們不能直接請求珍促。需要模擬客戶端,填寫一個header
最后
如果想要自動翻頁爬取的話兄墅,已西刺為例。只要在爬取一頁完成澳叉,自動切換下一頁就好
import requests
from bs4 import BeautifulSoup
for page in range(1,10):
res = requests.get('http://www.xicidaili.com/%d'%page,headers = { 'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20' })
soup = BeautifulSoup(res.content,'lxml')
table_tag = soup.find('table')
tr_list = table_tag.find_all('tr')
for index,tr_tag in enumerate(tr_list):
if index > 1:
td_list = list(filter(lambda x:x != '\n',tr_tag.contents))
print('ip: ' + td_list[1].string + ':' + td_list[2].string)