從零開始寫Python爬蟲 --- 1.6 爬蟲實踐: DOTA'菠菜'結果查詢
阿新 • • 發佈:2019-02-13
說起來目錄裡面本來是準備雙色球資訊查詢的,但是我一點都不懂這個啊,恰好身邊有個老賭棍,沉迷Dota飾品交易,俗稱 “菠菜”。老賭棍啊,老賭棍,能不能不要每天我說天台見。。。
這次的爬蟲功能十分的簡答,主要目的是延展一下bs4庫的使用。
目標分析:
看一看網站裡的資訊是怎麼排列的:
和上一次一樣 我們使用開發者工具,快速定位到比賽結果的div中:
有了上一次爬取百度貼吧的經驗。我們很容易就能發現,每一場比賽的資訊都儲存在:
<div class="matchmain bisai_qukuai">
這個div中。
這樣我們先利用bs4庫的findall()方法抓取到每個div,
再迴圈遍歷出每一條我們需要的資訊就大功告成了!
程式碼的實現:
抓取頭:
依舊是我們經常用的抓網頁到本地的程式碼框架,
def get_html(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return " ERROR "
主要處理函式:
def print_result(url):
'''
查詢比賽結果,並格式化輸出!
'''
html = get_html(url)
soup = bs4.BeautifulSoup(html,'lxml')
match_list = soup.find_all('div', attrs={'class': 'matchmain bisai_qukuai'})
for match in match_list:
time = match.find('div', attrs={'class': 'whenm'}).text.strip()
teamname = match.find_all('span', attrs={ 'class': 'team_name'})
#由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些註釋,方法如下:
if teamname[0].string[0:3] == 'php':
team1_name = "暫無隊名"
else:
team1_name = teamname[0].string
# 這裡我們採用了css選擇器:比原來的屬性選擇更加方便
team1_support_level = match.find('span', class_='team_number_green').string
team2_name = teamname[1].string
team2_support_level = match.find('span', class_='team_number_red').string
print('比賽時間:{},\n 隊伍一:{} 勝率 {}\n 隊伍二:{} 勝率 {} \n'.format(time,team1_name,team1_support_level,team2_name,team2_support_level))
這裡有些內容要想說一下:
- bs4css選擇器的使用:
原來我們在文件中查詢tag的時候,總是習慣使用這個方法:
find_all('name',attrs={})
這個方法的的確是很方便的幫我們定位元素,
之前的查詢中,我們只用到attrs={}字典中的一個class值。
如果單單通過class屬性來定位我們有更好的方式:css選擇器:
語法:
soup.find_all("a", class_="xxx")
這樣我們就能迅速的找到soup中的class為‘xxx’的元素了
- Comment型別的註釋檔案:
這次我們在爬取的時候,由於網站可能沒做好,有的隊伍名字查詢不到,就會顯示一個php的查詢註釋:
<div class="teamtext">
<span class="team_name"><?php phpinfo(); ?></span>
</div>`
這裡我選擇了硬編碼的方式來解決:
#由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些註釋,方法如下:
if teamname[0].string[0:3] == 'php':
team1_name = "暫無隊名"
else:
team1_name = teamname[0].string
由於是十分小的專案,可以這樣解決,但是如果是較大,
並且需要複用的情況,
我們來看看推薦的做法:
html = '''
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
'''
#可以看到,a標籤下的內容是一個註釋型別,但是如果我們直接輸出它的話
#會輸把註釋符號去掉的 Elsie:
print(soup.a.string) #Elsie
#所以為了過濾掉註釋型別,我們可以這樣做:
if type(soup.a.string)==bs4.element.Comment:
//TO DO
#上面通過一個簡單的型別判斷解決了這個問題。
整體程式碼:
'''
爬取Dota菠菜結果資訊
使用 requests --- bs4 線路
Python版本: 3.6
OS: mac os 12.12.4
'''
import requests
import bs4
def get_html(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return " ERROR "
def print_result(url):
'''
查詢比賽結果,並格式化輸出!
'''
html = get_html(url)
soup = bs4.BeautifulSoup(html,'lxml')
match_list = soup.find_all('div', attrs={'class': 'matchmain bisai_qukuai'})
for match in match_list:
time = match.find('div', attrs={'class': 'whenm'}).text.strip()
teamname = match.find_all('span', attrs={'class': 'team_name'})
#由於網站的構造問題,隊名有的時候會不顯示,所以我們需要過濾掉一些註釋,方法如下:
if teamname[0].string[0:3] == 'php':
team1_name = "暫無隊名"
else:
team1_name = teamname[0].string
# 這裡我們採用了css選擇器:比原來的屬性選擇更加方便
team1_support_level = match.find('span', class_='team_number_green').string
team2_name = teamname[1].string
team2_support_level = match.find('span', class_='team_number_red').string
print('比賽時間:{},\n 隊伍一:{} 勝率 {}\n 隊伍二:{} 勝率 {} \n'.format(time,team1_name,team1_support_level,team2_name,team2_support_level))
def main():
url= 'http://dota2bocai.com/match'
print_result(url)
if __name__ == '__main__':
main()
爬取結果:
經過這兩個小例子,大家也可以開始動手去寫自己的爬蟲了
你可能會遇到很多小問題,不要畏懼,一點一點的去解決
看著debug資訊,遇到不懂的就去Google,其實我們遇到的很多問題,
前人都已經遇到過,並且大多數時候都有很好地解決辦法。
如果還是不能解決,歡迎在我這裡留言~