前言
實戰(一)之使用自帶urllib和re正規表示式獲取電影詳情頁連結
其實大多情況下,python自帶的urllib和re正規表示式已經可以滿足我們的日常需求了,但是,聰明的世人怎麼會滿足於此呢,只有更好就沒有最好。所以,就誕生了requests和beautifulsoup這兩個作為爬蟲的黃金組合。而python的魅力就在於此,你可以找到很多好用易上手到讓你心頭一顫的第三方庫。
一、安裝&簡單使用入門。
1、安裝
使用Pip可以很方便的安裝:
pip install requests
pip install beautifulsoup4
2、requests 入門。
import requests
## get請求
r = requests.get('https://github.com/timeline.json')
r.json() ##如果是JSON 響應內容,使用r.json()會自動將json結果轉換成dict
r.content() ##二進位制相應內容
headers = {'user-agent': 'my-app/0.0.1'} #定製請求頭
r = requests.get('https://github.com/timeline.json', headers=headers)
payload = {'key1': 'value1', 'key2': 'value2'} #傳遞url引數
r = requests.get("http://httpbin.org/get", params=payload)
## post請求
payload = {'key1': 'value1', 'key2': 'value2'} ## post資料
r = requests.post("http://httpbin.org/post", data=payload)
## 上傳檔案
url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
複製程式碼
更多詳細的請檢視官方的中文文件,詳細易懂權威。
http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
3、beautifulsoup入門。
beautifulsoup可以快速的去定位HTML文件,HTML是用來描述網頁的一種超文字標記語言,不是一種程式語言。 如果你沒有HTML基礎,可以去花一天的時間瞭解下。 菜鳥教程--HTML
http://www.runoob.com/html/html-tutorial.html
注意的點
-
現在假設知道了HTML是個什麼東西,你會發現HTML就是由一層又一層的tag組成,每個tag節點有自己的class屬性或者其他屬性、自己的父tag、子tag以及兄弟tag,而beautifulsoup的作用就是通過這種蛛絲馬跡,輕易的把你要的凶手。。哦不目標節點揪出來,免去了寫正規表示式的繁瑣噩夢。
-
beautifulsoup對HTML的解釋是依賴第三方解釋庫的,常用的有html.parser、lxml、支援xml解釋的lxml-xml、html5Lib,各有優缺點,根據我的經驗,有時候使用beautifulsoup返回的待處理文字,會缺少一些tag節點,但是你又確定這不是動態載入的話,其實這是因為直譯器無法解釋,直接跳過導致的,這時候,可以更換直譯器嘗試一下。
常用的方法
我這裡只用下find和find_all作為例項,詳細的用法請去權威易懂的官方文件。 畢竟做搬運工是件很累且無意義的事情。
http://beautifulsoup.readthedocs.io/zh_CN/latest/
from bs4 import BeautifulSoup
##配合requests
r = requests.get('http://www.douban.com')
##一鍋待處理的soup湯
soup = BeautifulSoup(r.content,'lxml') #使用lxml解釋庫
print(soup)
複製程式碼
我們會得到如下的soup體,然後定位到紅色框的a塊。
通過屬性定位查詢該節點 (find)
a = soup.find('a',attrs={'class':'lnk-book'})
print(a)
print('連結: '+a['href'])
print('文字: '+a.text)
複製程式碼
返回包含所有該節點的列表(find_all)
a_s = soup.find_all('a')
print (a_s)
複製程式碼
提示:有時候需要先將目標範圍逐層縮小,這樣容易獲取目標節點。
二、爬取豆瓣圖書top250
分析頁面。
1、 我們點選底部的頁碼,會發現頁數是25的倍數,從0開始,這樣我們就可以構造對應頁的url了。
2、我們定位到每頁,查詢書本的資訊,獲取對應的url,下圖為每頁爬取到的書本詳情頁url。
3、在圖書的詳情頁,我們定位到如下元素。獲取該書的書名,評分和評分人數。
程式碼編寫
# -*- coding:utf-8 -*-
#author:waiwen
#email:iwaiwen@163.com
#time: 2017/12/3 12:27
from bs4 import BeautifulSoup
import requests
import random
#uer_agent庫,隨機選取,防止被禁
USER_AGENT_LIST = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
#請求網頁的程式碼整合
def get_response(url):
#random.choice從一個集合中隨機選出請求頭
headers = {'user-agent':random.choice(USER_AGENT_LIST)}
resp = requests.get(url,headers=headers)
resp.raise_for_status()
soup = BeautifulSoup(resp.content, 'lxml')
return soup
#找到每本書的連結
def get_book_url(page):
if page>10:
return []
num=(page-1)*25
url ='https://book.douban.com/top250?start=%s'%str(num)
soup = get_response(url)
book_div = soup.find('div', attrs={'class': 'indent'})
books = book_div.find_all('tr', attrs={'class': 'item'})
urls = [ book.td.a['href'] for book in books ]
print('獲取第%s頁'%page,urls)
return urls
#獲得每本書的資訊
def get_book_info(book_url):
soup = get_response(book_url)
div_info = soup.find('div',attrs={'id':'info'})
book_author = div_info.a.text.split(' ')[-1] #將空格去除
book = soup.find('div',attrs={'class':'rating_wrap clearbox'})
book_name= soup.find('span',attrs={'property':'v:itemreviewed'}).text
book_grade = book.find('strong',attrs={'class':'ll rating_num '}).text
book_man = book.find('a',attrs={'class':'rating_people'}).span.text
book_info ={}
book_info['name']=book_name
book_info['author']=book_author
book_info['rating_num'] = int(book_man)
book_info['grade'] = float(book_grade)
print(book_info)
return book_info
if __name__ == '__main__':
all_urls = []
#從第1頁到第10頁爬取,連結拼接到一起。
for page in range(1,11):
urls = get_book_url(page)
all_urls = all_urls+urls
print('獲取到的連結數:',len(all_urls))
out=''
for url in all_urls:
try:
info = get_book_info(url)
except Exception as e:
print(e)
continue
out=out+str(info)+'\n'
with open('douban_book_top250.txt','w') as f: #輸出到TXT檔案
f.write(out)
複製程式碼
總結
分析頁面,找到目標元素所在的tag節點,記錄其屬性,通過beautifulsoup的find和find_all找到該區域,然後進行相應的提取。這個過程中,要說明一下,使用單執行緒阻塞爬取250本書的資訊,比較耗時,計劃後面將會使用多執行緒進行改進,敬請期待喲。