實戰(zhàn)(一)使用自帶urllib和re正則表達式獲取電影詳情頁鏈接
前言
其實大多情況下卵史,python自帶的urllib和re正則表達式已經(jīng)可以滿足我們的日常需求了铝条,但是邓馒,聰明的世人怎么會滿足于此呢碴巾,只有更好就沒有最好。所以配并,就誕生了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參數(shù)
r = requests.get("http://httpbin.org/get", params=payload)
## post請求
payload = {'key1': 'value1', 'key2': 'value2'} ## post數(shù)據(jù)
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是用來描述網(wǎng)頁的一種超文本標記語言偷霉,不是一種編程語言迄委。
如果你沒有HTML基礎褐筛,可以去花一天的時間了解下。
菜鳥教程--HTML
注意的點
現(xiàn)在假設知道了HTML是個什么東西叙身,你會發(fā)現(xiàn)HTML就是由一層又一層的tag組成渔扎,每個tag節(jié)點有自己的class屬性或者其他屬性、自己的父tag信轿、子tag以及兄弟tag晃痴,而beautifulsoup的作用就是通過這種蛛絲馬跡,輕易的把你要的兇手财忽。倘核。哦不目標節(jié)點揪出來,免去了寫正則表達式的繁瑣噩夢即彪。
beautifulsoup對HTML的解釋是依賴第三方解釋庫的紧唱,常用的有html.parser、lxml隶校、支持xml解釋的lxml-xml漏益、html5Lib,各有優(yōu)缺點,根據(jù)我的經(jīng)驗深胳,有時候使用beautifulsoup返回的待處理文本绰疤,會缺少一些tag節(jié)點,但是你又確定這不是動態(tài)加載的話舞终,其實這是因為解釋器無法解釋轻庆,直接跳過導致的,這時候敛劝,可以更換解釋器嘗試一下榨了。
常用的方法
我這里只用下find和find_all作為實例,詳細的用法請去權威易懂的官方文檔攘蔽。 畢竟做搬運工是件很累且無意義的事情龙屉。
from bs4 import BeautifulSoup
##配合requests
r = requests.get('http://www.douban.com')
##一鍋待處理的soup湯
soup = BeautifulSoup(r.content,'lxml') #使用lxml解釋庫
print(soup)
我們會得到如下的soup體,然后定位到紅色框的a塊。
通過屬性定位查找該節(jié)點 (find)
a = soup.find('a',attrs={'class':'lnk-book'})
print(a)
print('鏈接: '+a['href'])
print('文字: '+a.text)
返回包含所有該節(jié)點的列表(find_all)
a_s = soup.find_all('a')
print (a_s)
提示:有時候需要先將目標范圍逐層縮小转捕,這樣容易獲取目標節(jié)點作岖。
二、爬取豆瓣圖書top250
分析頁面五芝。
1痘儡、 我們點擊底部的頁碼,會發(fā)現(xiàn)頁數(shù)是25的倍數(shù)枢步,從0開始沉删,這樣我們就可以構造對應頁的url了。
2醉途、我們定位到每頁矾瑰,查找書本的信息,獲取對應的url隘擎,下圖為每頁爬取到的書本詳情頁url殴穴。
3、在圖書的詳情頁货葬,我們定位到如下元素采幌。獲取該書的書名,評分和評分人數(shù)震桶。
代碼編寫
# -*- 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"
]
#請求網(wǎng)頁的代碼整合
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('獲取到的鏈接數(shù):',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節(jié)點淤堵,記錄其屬性寝衫,通過beautifulsoup的find和find_all找到該區(qū)域,然后進行相應的提取拐邪。這個過程中慰毅,要說明一下,使用單線程阻塞爬取250本書的信息扎阶,比較耗時汹胃,計劃后面將會使用多線程進行改進,敬請期待喲东臀。