從零開始寫Python爬蟲 --- 1.6 爬蟲實踐: DOTA'菠菜'結果查詢

說起來目錄裡面本來是準備雙色球信息查詢的,但是我一點都不懂這個啊,恰好身邊有個老賭棍,沉迷Dota飾品交易,俗稱 「菠菜」。老賭棍啊,老賭棍,能不能不要每天我說天台見。。。

這次的爬蟲功能十分的簡答,主要目的是延展一下bs4庫的使用。

目標分析:

我們查詢比賽結果的網址是:dota2bocai.com/match

看一看網站里的信息是怎麼排列的:

和上一次一樣 我們使用開發者工具,快速定位到比賽結果的div中:

有了上一次爬取百度貼吧的經驗。我們很容易就能發現,每一場比賽的信息都保存在:

<div class="matchmain bisai_qukuai">n

這個div中。

這樣我們先利用bs4庫的findall()方法抓取到每個div,

再循環遍歷出每一條我們需要的信息就大功告成了!

代碼的實現:

抓取頭:

依舊是我們經常用的抓網頁到本地的代碼框架,

def get_html(url):n try:n r = requests.get(url, timeout=30)n r.raise_for_status()n r.encoding = r.apparent_encodingn return r.textn except:n return " ERROR "n

主要處理函數:

def print_result(url):n n 查詢比賽結果,並格式化輸出!n n html = get_html(url)n soup = bs4.BeautifulSoup(html,lxml)n match_list = soup.find_all(div, attrs={class: matchmain bisai_qukuai})n for match in match_list:n time = match.find(div, attrs={class: whenm}).text.strip()n teamname = match.find_all(span, attrs={class: team_name})n n n #由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些注釋,方法如下:n if teamname[0].string[0:3] == php:n team1_name = "暫無隊名"n else:n team1_name = teamname[0].stringn n # 這裡我們採用了css選擇器:比原來的屬性選擇更加方便n team1_support_level = match.find(span, class_=team_number_green).stringnn team2_name = teamname[1].stringn team2_support_level = match.find(span, class_=team_number_red).stringnn print(比賽時間:{},n 隊伍一:{} 勝率 {}n 隊伍二:{} 勝率 {} n.format(time,team1_name,team1_support_level,team2_name,team2_support_level))n

這裡有些內容要想說一下:

  • bs4css選擇器的使用:

原來我們在文檔中查詢tag的時候,總是習慣使用這個方法:

find_all(name,attrs={})n

這個方法的的確是很方便的幫我們定位元素,

之前的查詢中,我們只用到attrs={}字典中的一個class值。

如果單單通過class屬性來定位我們有更好的方式:css選擇器:

語法:

soup.find_all("a", class_="xxx")n

這樣我們就能迅速的找到soup中的class為『xxx』的元素了

  • Comment類型的注釋文件:

這次我們在爬取的時候,由於網站可能沒做好,有的隊伍名字查詢不到,就會顯示一個php的查詢注釋:

<div class="teamtext">n<span class="team_name"><?php phpinfo(); ?></span>n</div>`n

這裡我選擇了硬編碼的方式來解決:

#由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些注釋,方法如下:n if teamname[0].string[0:3] == php:n team1_name = "暫無隊名"n else:n team1_name = teamname[0].stringn

由於是十分小的項目,可以這樣解決,但是如果是較大,

並且需要復用的情況,

我們來看看推薦的做法:

html = n<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>nn#可以看到,a標籤下的內容是一個注釋類型,但是如果我們直接輸出它的話n#會輸把注釋符號去掉的 Elsie:nnprint(soup.a.string) #Elsienn#所以為了過濾掉注釋類型,我們可以這樣做:nnif type(soup.a.string)==bs4.element.Comment:n //TO DOn#上面通過一個簡單的類型判斷解決了這個問題。n

整體代碼:

n爬取Dota菠菜結果信息n使用 requests --- bs4 線路nPython版本: 3.6nOS: mac os 12.12.4nnnimport requestsnimport bs4nndef get_html(url):n try:n r = requests.get(url, timeout=30)n r.raise_for_status()n r.encoding = r.apparent_encodingn return r.textn except:n return " ERROR "nndef print_result(url):n n 查詢比賽結果,並格式化輸出!n n html = get_html(url)n soup = bs4.BeautifulSoup(html,lxml)n match_list = soup.find_all(div, attrs={class: matchmain bisai_qukuai})n for match in match_list:n time = match.find(div, attrs={class: whenm}).text.strip()n teamname = match.find_all(span, attrs={class: team_name})n n n #由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些注釋,方法如下:n if teamname[0].string[0:3] == php:n team1_name = "暫無隊名"n else:n team1_name = teamname[0].stringn n # 這裡我們採用了css選擇器:比原來的屬性選擇更加方便n team1_support_level = match.find(span, class_=team_number_green).stringnn team2_name = teamname[1].stringn team2_support_level = match.find(span, class_=team_number_red).stringnn print(比賽時間:{},n 隊伍一:{} 勝率 {}n 隊伍二:{} 勝率 {} n.format(time,team1_name,team1_support_level,team2_name,team2_support_level))nnnndef main():n url= http://dota2bocai.com/matchn print_result(url)nnif __name__ == __main__:n main()n

爬取結果:

經過這兩個小例子,大家也可以開始動手去寫自己的爬蟲了

你可能會遇到很多小問題,不要畏懼,一點一點的去解決

看著debug信息,遇到不懂的就去Google,其實我們遇到的很多問題,

前人都已經遇到過,並且大多數時候都有很好地解決辦法。

如果還是不能解決,歡迎在我這裡留言~

每天的學習記錄都會 同步更新到:

微信公眾號: findyourownway

知乎專欄:從零開始寫Python爬蟲 - 知乎專欄

blog : www.ehcoblog.ml

Github: Ehco1996/Python-crawler

推薦閱讀:

《Python Linux系統管理與自動化運維》收到的評價
發布Python桌面應用程序(入門)
100行深度學習文本分類
UserDict、UserString、UserList存在的意義

TAG:Python | Python入门 | 爬虫 |