實戰(二)輕鬆使用requests庫和beautifulsoup爬連接

前言

實戰(一)之使用自帶urllib和re正則表達式獲取電影詳情頁連接html

其實大多狀況下,python自帶的urllib和re正則表達式已經能夠知足咱們的平常需求了,可是,聰明的世人怎麼會知足於此呢,只有更好就沒有最好。因此,就誕生了requests和beautifulsoup這兩個做爲爬蟲的黃金組合。而python的魅力就在於此,你能夠找到不少好用易上手到讓你心頭一顫的第三方庫。html5

1、安裝&簡單使用入門。

一、安裝

使用Pip能夠很方便的安裝:python

pip install requestsgit

pip install beautifulsoup4github

二、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編程

三、beautifulsoup入門。

beautifulsoup能夠快速的去定位HTML文檔,HTML是用來描述網頁的一種超文本標記語言,不是一種編程語言。 若是你沒有HTML基礎,能夠去花一天的時間瞭解下。 菜鳥教程--HTMLjson

http://www.runoob.com/html/html-tutorial.htmlbash

注意的點
  • 如今假設知道了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塊。

image.png

經過屬性定位查找該節點 (find)

a = soup.find('a',attrs={'class':'lnk-book'})
    print(a)
    print('連接: '+a['href'])
    print('文字: '+a.text)
複製代碼

image.png

返回包含全部該節點的列表(find_all)

a_s = soup.find_all('a')
print (a_s)
複製代碼

image.png

提示:有時候須要先將目標範圍逐層縮小,這樣容易獲取目標節點。

2、爬取豆瓣圖書top250

分析頁面。

一、 咱們點擊底部的頁碼,會發現頁數是25的倍數,從0開始,這樣咱們就能夠構造對應頁的url了。

image.png

二、咱們定位到每頁,查找書本的信息,獲取對應的url,下圖爲每頁爬取到的書本詳情頁url。

image.png

image.png

三、在圖書的詳情頁,咱們定位到以下元素。獲取該書的書名,評分和評分人數。

image.png

image.png

代碼編寫

# -*- 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)

複製代碼

image.png

總結

分析頁面,找到目標元素所在的tag節點,記錄其屬性,經過beautifulsoup的find和find_all找到該區域,而後進行相應的提取。這個過程當中,要說明一下,使用單線程阻塞爬取250本書的信息,比較耗時,計劃後面將會使用多線程進行改進,敬請期待喲。

相關文章
相關標籤/搜索