最近在學習py,整理一下自己的學習記錄,算是備忘了。
py新手,僅供新手小伙伴們學習
1.BeautifulSoup中文文檔地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#extract
概覽
我們平常爬蟲了解這幾個類就可以了
上面這個圖 我們最常用用到的就是Tag
和NavigableString
我們指導html是標記語言,我們想爬的數據都是被格式各樣的標簽嵌套的。
像<head>數據</head>
而BeautifulSoup 簡單的來說就是找標簽取數據,總體來說學習成本特別低,容易上手。
我們來一步一分分析 對象的創建 以及 返回的類型
1.BeautifulSoup 的初始化
soup = BeautifulSoup(content,'lxml')
soup 是一個BeautifulSoup類型,從上面的繼承關系看其實就是一個Tag類型。一個大Tag包含著無數的小Tag
2.初步定位tag
tag = soup.find('table')
返回的是一個也是tag類型
tags = soup.find_all('table')
返回的是一個ResultSet 其實就是一個list類型的子類,在bs4.element
文件中有說明
3.具體定位tag
當我們獲取大體的Tag對象時,我們如果想獲取其中子Tag的數據
這里要分2種情況
一 。。標記有屬性標記
直接再通過第二步的方法繼續獲取
二 。。沒有屬性標記 如<td></td>
str_list = tag.contents
返回一個list對象
str_list_iterator = tag.children
返回一個list_iterator
4.獲取數據
首先要說一點 上面第三步說的獲取具體的tag,其實通過contents和children獲取的不只是Tag對象,還有NavigableString對象。這點一定要清楚。
直接通過string
屬性來獲取就可以了
實戰
爬取ip代理網站(2種不同的類型),獲取代理ip。
1.西刺免費代理IPhttp://www.xicidaili.com/nn
網頁源代碼 我就不貼在這邊了
源代碼 大家自己另開的網頁自己看下
通過分析源代碼,我們很清楚的發現我們數據實在table
標簽內(而且頁面只有一個table標簽)
1.初始化
soup = BeautifulSoup(res.content,'lxml')
2.定位大體的Tag(這一步可以省略)
table_tag = soup.find('table')
3.定位具體的Tag
tr_list = table_tag.find_all('tr')
4.得到數據
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)
我們分析源碼可以發現 第1,2個tr 是表頭,不包含我們想要的數據,可以跳過。
在contents獲取或有子節點的時候,我們會發現返回的不只有tag對象還有‘\n’字符的None類型。所以我們要用filter
過濾這些噪音數據。
在過濾之后,我們可以清楚的看到 第二個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)
這里在請求數據的是時候,因為西刺有防爬處理。我們不能直接請求。需要模擬客戶端,填寫一個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)