Python爬蟲實例(一)爬取百度貼吧帖子中的圖片


程序功能說明:爬取百度貼吧帖子中的圖片,用戶輸入貼吧名稱和要爬取的起始和終止頁數即可進行爬取。

思路分析:

一、指定貼吧url的獲取

例如我們進入秦時明月吧,提取並分析其有效url如下

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88

?后面為查詢字符串,“%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88“是貼吧名稱“秦時明月”的url編碼。

這樣我們就可以通過構造請求進入每一個貼吧了,代碼實現如下:

import urllib
# 貼吧url前半部分
url = "http://tieba.baidu.com/f?" value = raw_input("請輸入要爬取的貼吧名稱:")
# 將查詢字符串轉換為url編碼形式 key
= urllib.urlencode({"kw":value})
# 組合完整的貼吧url url = url + key
# 查看完整url
print url

運行程序,這里輸入“天行九歌”作為演示,可以得到天行九歌吧的完整鏈接如下:

http://tieba.baidu.com/f?kw=%CC%EC%D0%D0%BE%C5%B8%E8

這樣就可以獲取任意貼吧的鏈接了。

 

 二獲取貼吧指定頁數的鏈接:

我們進入天行九歌吧,取出該貼吧第2頁到底4頁的url,如下:

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=50

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=100

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=150

我們發現,每一頁的url變化的是pn的值,依次增加50,結合上面貼吧完整的url,要想獲得每一頁的鏈接可以如下實現:

import urllib
url = "http://tieba.baidu.com/f?"
value = raw_input("請輸入要爬取的貼吧名稱:")
key = urllib.urlencode({"kw":value})
# 貼吧完整url
url = url + key begin_page = int(raw_input("請輸入起始頁:")) end_page = int(raw_input("請輸入終止頁:")) for page in range(begin_page, end_page+1): pn = (page-1)*50
  # 組合出貼吧每一頁的url full_url = url + "&pn=" + str(pn) print full_url

運行程序,輸入貼吧名稱:“天行九歌”,再輸入起始頁1,終止頁5,可得到如下結果:

 

 這樣我們就可以拿到貼吧每一頁的鏈接了。

 

獲取貼吧每一頁中帖子的鏈接:

選擇一個帖子,首先查看該帖子的元素得到:

<a href="/p/5344262338" title="端木蓉為何一直不蘇醒" target="_blank" class="j_th_tit ">端木蓉為何一直不蘇醒</a>

然后進入這個帖子取得它的完整鏈接:

http://tieba.baidu.com/p/5344262338

分析可得:完整鏈接可由兩部分組成,http://tieba.baidu.com和/p/5344262338,后面的部分可以從頁面源碼中提取,使用xpath規則提取如下:

xpath提取規則://a[@class="j_th_tit"]/@href(先在瀏覽器中使用插件匹配,規則很多,找到合適的就行)

 下面選擇第二頁帖子鏈接做如下演示

# -*- coding: utf-8 -*-
import urllib2
from lxml import etree
# 貼吧第二頁url url
= "http://tieba.baidu.com/f?kw=%E5%A4%A9%E8%A1%8C%E4%B9%9D%E6%AD%8C&pn=50" request = urllib2.Request(url) html = urllib2.urlopen(request).read() content = etree.HTML(html)
# 匹配這一頁中所以帖子鏈接的后半部分 link_list
= content.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href') for link in link_list:
  # 組合為完整帖子鏈接 fulllink
= "http://tieba.baidu.com" + link print fulllink

運行程序,則可取該頁中帖子的鏈接(展示部分)

這樣就拿到了每個帖子的鏈接了。

 

獲取每一個帖子中圖片的鏈接:

進入一個帖子,找到發布的圖片查看元素:

<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=c1cc6b66b819ebc4c0787691b227cf79/3577812397dda14415c938b1b9b7d0a20df48615.jpg" pic_ext="jpeg" size="39874" height="600" width="450">

使用xpath規則提取圖片鏈接:

xpath提取規則://img[@class="BDE_Image"]/@src

取上面第一個帖子做演示:

# -*- coding: utf-8 -*-
import urllib2
from lxml import etree
# 第一個帖子的url url
= "http://tieba.baidu.com/p/5341810557" headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} request = urllib2.Request(url, headers = headers) html = urllib2.urlopen(request).read() content = etree.HTML(html) # 匹配出帖子中的圖片鏈接 link_list = content.xpath('//img[@class="BDE_Image"]/@src') for link in link_list: print link

運行程序,取得帖子中圖片鏈接(展示部分)

 到現在為止,我們已經可以進入任意一個貼吧,獲取每個貼吧指定頁數的響應,並且可以拿到每個帖子中的圖片鏈接,接下來要做的就是以圖片鏈接發送請求獲取響應文件保存下來即可。

 

保存圖片到本地:

import urllib2
# 取得的圖片鏈接 url
= "http://imgsa.baidu.com/forum/w%3D580/sign=b42c88339945d688a302b2ac94c37dab/541d5d510fb30f243576ad03c395d143ac4b0352.jpg" headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} request = urllib2.Request(url, headers = headers) image = urllib2.urlopen(request).read()
# 將圖片鏈接后10位作為圖片文件名稱 filename
= url[-10:]
# 保存圖片到本地 with open(filename,
"wb") as f: f.write(image)

運行程序,圖片就會保存到當前的工作目錄中。

 

完整程序

整個過程就是這樣了,根據上面的分析,寫出的完整程序如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib
import urllib2
from lxml import etree

def loadPage(url):
    """
        作用:根據url發送請求,獲取服務器響應文件
        url: 需要爬取的url地址
    """
    headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
    request = urllib2.Request(url, headers=headers)
    html = urllib2.urlopen(request).read()
    content = etree.HTML(html)
    # 匹配每個帖子url的后半部分
    link_list = content.xpath('//a[@class="j_th_tit"]/@href')
    for link in link_list:
        # 組合為每個帖子的完整鏈接
        fulllink = "http://tieba.baidu.com" + link
        loadImage(fulllink)

def loadImage(link):
    """
        作用:取出每個帖子里的每個圖片連接
        link:每個帖子的鏈接
    """
    headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
    request = urllib2.Request(link, headers = headers)
    html = urllib2.urlopen(request).read()
    content = etree.HTML(html)
    # 匹配帖子里發送的圖片鏈接
    link_list = content.xpath('//img[@class="BDE_Image"]/@src')
    # 取出每個圖片的連接
    for link in link_list:
        writeImage(link)

def writeImage(link):
    """
        作用:將圖片保存到本地
        link:圖片連接
    """
    headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
    request = urllib2.Request(link, headers = headers)
    image = urllib2.urlopen(request).read()
    filename = link[-10:]
    with open(filename, "wb") as f:
        f.write(image)
    print "已經成功下載 "+ filename

def tiebaSpider(url, beginPage, endPage):
    """
        作用:負責組合處理貼吧每個頁面的url
        url : 貼吧url的前部分
        beginPage : 起始頁
        endPage : 結束頁
    """
    for page in range(beginPage, endPage + 1):
        pn = (page - 1) * 50
        fullurl = url + "&pn=" + str(pn)
        loadPage(fullurl)
        print "謝謝使用"

if __name__ == "__main__":
    kw = raw_input("請輸入需要爬取的貼吧名:")
    beginPage = int(raw_input("請輸入起始頁:"))
    endPage = int(raw_input("請輸入結束頁:"))
    url = "http://tieba.baidu.com/f?"
    key = urllib.urlencode({"kw": kw})
    fullurl = url + key
    tiebaSpider(fullurl, beginPage, endPage)

 運行程序,輸入你要爬取的貼吧名稱和要爬取的頁數,圖片就可以下載到你的工作目錄下了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM