學習爬蟲基礎5-一個簡單的小案例

爬去百度貼吧中的html文檔下來

會使用到urllib中的 urllib.urlencode() 方法來編碼發送請求時候的 請求參數
URL編碼轉換:urllib的urlencode()

urllib 模塊僅可以接受URL,不能創建 設置了headers 的Request 類實例;

但是 urllib 提供 urlencode 方法用來產生GET查詢字符串,而 urllib2 則沒有。(這是 urllib 和 urllib2 經常一起使用的主要原因)

編碼工作使用urllib的urlencode()函數,幫我們將key:value這樣的鍵值對,轉換成"key=value"這樣的字符串,解碼工作可以使用urllib的unquote()函數。( 注意,不是urllib2.urlencode())
# IPython2 中的測試結果
In [1]: import urllib

In [2]: word = {"wd" : "百度"}

# 通過urllib.urlencode()方法,將字典鍵值對按URL編碼轉換,從而能被web服務器接受。
In [3]: urllib.urlencode(word)  
Out[3]: "wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2"

# 通過urllib.unquote()方法,把 URL編碼字符串,轉換回原先字符串。
In [4]: print urllib.unquote("wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2")
wd=百度

爬貼吧中的內容 代碼演示

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib
import urllib2
import os
import time


def get_request(url):
    """發起請求"""
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1'}
    request = urllib2.Request(url, headers=header)
    response = urllib2.urlopen(request, timeout=5)
    if response.getcode() == 200:
        html = response.read()
        return html
    else:
        print('請求失敗....')


def write_html(html, page):
    """爬取出來的內容寫入到文件中"""
    if not os.path.exists('./貼吧'):
        os.mkdir('./貼吧')
    file_path = os.path.join('./貼吧', '貼吧的第' + str(page) + '內容.html')
    try:
        with open(file_path, 'w') as fp:
            fp.write(html)
        print('保存成功')
    except Exception as err:
        print(err)


def spider(name, start_page, end_page):
    """爬蟲主程序"""
    base_url = 'https://tieba.baidu.com/f?'
    keyword = {"kw": name}
    # 編碼
    keyword = urllib.urlencode(keyword)
    start_time = time.time()
    for page in range(start_page, end_page + 1):
        pn = urllib.urlencode({'pn': page * 50})
        url = base_url + keyword + "&" + pn
        html = get_request(url)
        write_html(html, page)
    print "結束時間", time.time() - start_time


def main():
    """程序的入口"""
    # name = raw_input("請輸入你要爬取的貼吧的名稱:>>>")
    name = "美女"
    start_page = int(raw_input('請輸入開始的頁碼:>>>'))
    end_page = int(raw_input('請輸入結束的頁碼:>>>'))
    spider(name, start_page, end_page)


if __name__ == "__main__":
    main()

加入多線程

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib
import urllib2
import os
from threading import Thread
import threading
import time


def get_request(url):
    """發起請求"""
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1'}
    request = urllib2.Request(url, headers=header)
    try:
        response = urllib2.urlopen(request, timeout=5)
        if response.getcode() == 200:
            html = response.read()
            return html
        else:
            print('請求失敗....')
    except Exception as err:
        print(err)


def write_html(html, page):
    """爬取出來的內容寫入到文件中"""
    file_path = os.path.join('./貼吧', '貼吧的第' + str(page) + '內容.html')
    try:
        with open(file_path, 'w') as fp:
            fp.write(html)
        print('保存成功')
    except Exception as err:
        print(err)


def thread_task(url, page):
    """多線程執行任務的函數"""
    html = get_request(url)
    write_html(html, page)
    print(threading.current_thread().name, url)


def spider(name, start_page, end_page):
    """爬蟲主程序"""
    base_url = 'https://tieba.baidu.com/f?'
    keyword = {"kw": "美女"}

    # 編碼
    keyword = urllib.urlencode(keyword)
    t_list = []  # 存放建立的線程
    start_time = time.time()
    for page in range(start_page, end_page + 1):
        pn = urllib.urlencode({'pn': page * 50})
        url = base_url + keyword + "&" + pn
        # 創建線程對象
        t = Thread(target=thread_task, args=(url, page))
        t_list.append(t)
        # 開啓線程
        t.start()
     # 使用join 加入等待 線程結束
    for t in t_list:  # 遍歷線程加入等待
        t.join()
    print ("結束時間", time.time() - start_time)


def main():
    """程序的入口"""
    # name = raw_input("請輸入你要爬取的貼吧的名稱:>>>")
    name = "美女"
    start_page = int(raw_input('請輸入開始的頁碼:>>>'))
    end_page = int(raw_input('請輸入結束的頁碼:>>>'))
    spider(name, start_page, end_page)


if __name__ == "__main__":
   # 判斷文件夾的程序放在了主程序中 防止多個線程同時去執行這段代碼 這裏沒有使用線程鎖
    if not os.path.exists('./貼吧'):
        os.mkdir('./貼吧')
    main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章