從零開始寫Python爬蟲 --- 1.6 爬蟲實踐: DOTA'菠菜'結果查詢
說起來目錄裡面本來是準備雙色球信息查詢的,但是我一點都不懂這個啊,恰好身邊有個老賭棍,沉迷Dota飾品交易,俗稱 「菠菜」。老賭棍啊,老賭棍,能不能不要每天我說天台見。。。
這次的爬蟲功能十分的簡答,主要目的是延展一下bs4庫的使用。
目標分析:
我們查詢比賽結果的網址是:http://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
語法:
soup.find_all("a", class_="xxx")n
- 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.mlGithub: Ehco1996/Python-crawler
推薦閱讀:
※《Python Linux系統管理與自動化運維》收到的評價
※發布Python桌面應用程序(入門)
※100行深度學習文本分類
※UserDict、UserString、UserList存在的意義