爬蟲-BeautifulSoup簡單分析和學習

weixin_34249678發表於2017-02-26

最近在學習py,整理一下自己的學習記錄,算是備忘了。
py新手,僅供新手小夥伴們學習
1.BeautifulSoup中文文件地址https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#extract

概覽
1106106-3eb8a520951011b1.png
Class Diagram.png

我們平常爬蟲瞭解這幾個類就可以了

上面這個圖 我們最常用用到的就是TagNavigableString

我們指導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)

相關文章