貼吧圖片爬蟲進階:在上次的第一個小爬蟲事後,用了幾回發現每爬一個帖子,都要本身手動輸入帖子連接,WTF這程序簡直反人類!不行了不行了得改進改進。html
在這期間研究了下Xpath:python
Xpath是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。正則表達式
簡單點來講就是能讓你的爬蟲經過標籤的id、class、name等屬性能夠獲取到標籤的屬性或內容的一門語言,就不用去寫討厭的正則表達式了(剛開始用正則人都要炸了)學習
Xpath的學習視頻呢,在這裏--->Gourl
固然其實用re也能實現,廢話也很少說了,開始正題了spa
咱們的目標固然是:壁紙吧、萌妹子、爆照吧等等等等線程
做爲一個紳士仍是以壁紙吧來作示範吧:http://tieba.baidu.com/f?kw=%E5%A3%81%E7%BA%B8&ie=utf-8code
打開壁紙吧視頻
經過右鍵檢查、或是查看源碼找到每一個帖子的標籤xml
帖子的標籤在這裏
<a href="/p/4686986115" title="【壁紙】江湖多風雨,天下已入秋" target="_blank" class="j_th_tit ">【壁紙】江湖多風雨,天下已入秋</a>
應該就是href後面的哪一個 "/p/4686986115" 了
點進去果真,就是在前面多了串 http://tieba.baidu.com
OK!那把連接爬取出來就至關容易了:
from lxml import etree def getArticleLinks(url): html = requests.get(url) Selector = etree.HTML(html.text) # 經過Xpath 獲取每一個帖子的url後綴 url_list = Selector.xpath('//div[@class="threadlist_lz clearfix"]/div/a/@href') # 在每一個後綴前加上百度貼吧的url前綴 for i in range(len(url_list)): url_list[i] = 'http://tieba.baidu.com' + url_list[i] return url_list
先是一個帖子的圖片下載:
def get_img(url): html = requests.get(url) # 這裏用Xpath或者以前的re拿到img_url_list Selector = etree.HTML(html.text) img_url_list = Selector.xpath('//*[@class="BDE_Image"]/@src') pic_name = 0 # 下載圖片 for each in img_url_list: urllib.urlretrieve(each, 'pic_%s.jpg' % pic_name) pic_name += 1
其實這樣已經差很少了,再來個循環每一個帖子連接來一次 get_img 就能夠獲取到全部的圖片,可是這樣的話:
個人想法是建一個downloads文件夾,而後在裏面按帖子分文件夾存放下載下來的圖片
# 該目錄下建立一個downloads文件夾存放下載圖片 if not os.path.exists('downloads'): os.mkdir('downloads')
固然是沒有的時候創建,有的話就能夠不用了
而後按帖子分文件夾
# 這裏把帖子url的後綴做爲文件夾名,由於不能有'/'因此把它替換成了'' img_dir = 'downloads/' + url_list[i][23:].replace("/", '') if not os.path.exists(img_dir): os.mkdir(img_dir)
而後就能夠下載了:
def download_img(url_list): if not os.path.exists('downloads'): os.mkdir('downloads') for each in url_list: img_dir = 'downloads/' + each[23:].replace("/", '') if not os.path.exists(img_dir): os.mkdir(img_dir) get_img(each)
然而並無一個個圖片按帖子放好,文件夾是建好了。
通過研究發現,應該在 get_img 以前應該先把當前目錄改成要放的文件夾目錄下
os.chdir(path) 能夠用來改變python當前所在的文件夾
而後在下載完一個帖子後得移回當前目錄,最後的代碼就是:
def download_img(url_list): # 該目錄下建立一個downloads文件夾存放下載圖片 if not os.path.exists('downloads'): os.mkdir('downloads') root_path = os.getcwd() for each in url_list: img_dir = 'downloads/' + each[23:].replace("/", '') if not os.path.exists(img_dir): os.mkdir(img_dir) os.chdir(img_dir) get_img(each) os.chdir(root_path)
啪啪啪啪啪[完美]
老樣子和以前的第一個小爬蟲同樣,添加一些交互。
不過我發現,一個貼吧第一頁的帖子也賊多,而後因爲爬蟲暫時仍是單線程的
因此如果要將整個第一頁爬完,也是要花挺多時間,就稍微修改了下,加了一個帖子個數的輸入
最終的代碼:
# coding:utf-8 import requests import os import urllib import re from lxml import etree # 經過url獲取每一個帖子連接 def getArticleLinks(url): html = requests.get(url) Selector = etree.HTML(html.text) # 經過Xpath 獲取每一個帖子的url後綴 url_list = Selector.xpath('//div[@class="threadlist_lz clearfix"]/div/a/@href') # 在每一個後綴前加上百度貼吧的url前綴 for i in range(len(url_list)): url_list[i] = 'http://tieba.baidu.com' + url_list[i] return url_list # 經過所給帖子連接,下載帖子中全部圖片 def get_img(url): html = requests.get(url) Selector = etree.HTML(html.text) img_url_list = Selector.xpath('//*[@class="BDE_Image"]/@src') pic_name = 0 for each in img_url_list: urllib.urlretrieve(each, 'pic_%s.jpg' % pic_name) pic_name += 1 # 爲每一個帖子建立獨立文件夾,並下載圖片 def download_img(url_list,page): # 該目錄下建立一個downloads文件夾存放下載圖片 if not os.path.exists('downloads'): os.mkdir('downloads') root_path = os.getcwd() for i in range(page): img_dir = 'downloads/' + url_list[i][23:].replace("/", '') if not os.path.exists(img_dir): os.mkdir(img_dir) os.chdir(img_dir) get_img(url_list[i]) os.chdir(root_path) if __name__ == '__main__': print u'-----貼吧圖片爬取裝置2.0-----' print u'請輸入貼吧地址:', targetUrl = raw_input('') if not targetUrl: print u'---沒有地址輸入正在使用默認地址(baidu壁紙吧)---' targetUrl = 'http://tieba.baidu.com/f?kw=%E5%A3%81%E7%BA%B8&ie=utf-8' page = '' while True: print u'請輸入你要下載的帖子數:', page = raw_input('') if re.findall(r'^[0-9]*[1-9][0-9]*$',page): page = int(page) break print u'----------正在下載圖片---------' ArticleLinks = getArticleLinks(targetUrl) download_img(ArticleLinks,page) print u'-----------下載成功-----------' raw_input('Press Enter to exit')
界面:
不要臉的說自我感受良好23333
結構是這樣滴
內容(爬取的內容怎麼和我不同?我無論23333)
# 結尾的啪啪啪啪啪