目標網站:http://bbs.fengniao.com/
使用框架:scrapyhtml
由於有不少模塊的方法都還不是很熟悉,全部本次爬蟲有不少代碼都用得比較笨,但願各位讀者能給處意見mysql
首先建立好爬蟲項目,並使用crawl模板建立爬蟲文件正則表達式
經過觀察論壇的規律得出,不少貼子的頁數每每大於一頁,那麼要將貼子裏各頁的圖片下載到同一文件夾內,而且不能重名,就是獲取到當前的頁碼數,已頁碼數+天然數的方式命令文件。
發現scrapy自動爬蟲會爬不少重複的頁面,度娘後得出兩個解決方法,第一個是用布隆過濾器,布隆過濾器相對於目前的我來講太過深奧,因而便採用了將URL寫入mysql的方式,經過mysql鍵的惟一性來去重複。sql
先編寫items文件數據庫
import scrapy class FengniaoItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title=scrapy.Field() #定義貼子名 images=scrapy.Field() #定義圖片連接 act=scrapy.Field() #定義頁碼數 thisurl=scrapy.Field() #定義當前url
其次是爬蟲文件,這裏命名爲s1.py瀏覽器
# -*- coding: utf-8 -*- import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from fengniao.items import FengniaoItem from scrapy import Request class S1Spider(CrawlSpider): name = 's1' allowed_domains = ['bbs.fengniao.com'] #start_urls = ['http://bbs.fengniao.com/'] def start_requests(self): url='http://bbs.fengniao.com/forum/forum_101.html/' #爬蟲開始的網址 ua={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36"} #設置瀏覽器ua模擬瀏覽器 yield Request(url,headers=ua) rules = ( Rule(LinkExtractor(allow=r'forum/'), callback='parse_item', follow=True), #allow=r'forum/' 設置爬取的網址的規律 ) def parse_item(self, response): item = FengniaoItem() item["thisurl"]=response.url #獲取當前頁面 item["title"]=response.xpath("/html/head/title/text()").extract() #獲取當前標題 item["images"]=response.xpath("//div[@class='img']//img/@src").extract() #獲取當前的圖片url item["act"]=response.xpath("//a[@class='act']/text()").extract() #獲取當前的頁碼 #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract() #i['name'] = response.xpath('//div[@id="name"]').extract() #i['description'] = response.xpath('//div[@id="description"]').extract() return item
固然啦,在settings.py裏要開啓pipelines 設置瀏覽器ua
而後咱們在pipelines.py裏開始處理咱們的爬到的東西框架
# -*- coding: utf-8 -*- import os import urllib.request import re import pymysql # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html class FengniaoPipeline(object): def process_item(self, item, spider): images=item["images"] #將圖片連接列表賦給images變量 thisurl = item["thisurl"] #將當前網址賦值費thisurl變量 conn=pymysql.connect(host='127.0.0.1',user='root',passwd='root',db='dd',charset='utf8') #建立數據庫鏈接 cursor=conn.cursor() #建立遊標 sql="insert into fengniao(link) values('" + thisurl + "')" 編寫數據庫代碼將當前連接插入數據庫 try: #作一個異常處理,若是能夠插進數據庫,說明當前網址沒有爬出過 cursor.execute(sql) conn.commit() if len(images)>0: #監測當前網址圖片連接是否存在 ,若是存在則執行下面的操做 title = item["title"][0] #將帖子名提取出來並賦值給title new_title = title.replace("【有圖】", "") #使用replace方法將【有圖】 去掉 act = item["act"][0] # 當前頁碼數 #提取當前的頁碼數並賦值給act print(act) print(thisurl) folder = "E:/PAS/fengniao1/" + new_title + '/' # 構造文件夾目錄 以帖子名命名 folder_test = os.path.exists(folder) # 監測文件夾是否存在 if not folder_test: #若是文件夾不存在 os.mkdir(folder) #建立文件夾 print("建立文件夾"+new_title+"成功") else: #若是文件夾存在 print("文件夾"+new_title+"已存在") print("一共有" + str(len(images)) + "張圖片") for i in range(0, len(images)): #使用for循環依次輸出圖片地址 pat='(.*?)?imageView' #觀察得出,圖片的地址爲小圖地址,因此使用正則表達式處理一下圖片地址,獲得高品質圖片的地址 new_images=re.compile(pat).findall(images[i]) #獲得大圖圖片地址列表 #print(new_images) num=int(act)-1 #處理一下頁碼數 print("正在下載" + str(num) + str(i) + "張圖片") file = folder + str(num) + str(i) + ".jpg" #構造圖片名稱,爲當前(頁面數-1)+天然數 urllib.request.urlretrieve(new_images[0], filename=file) #使用urllib.request.urlretrieve 方法下載圖片 # for i in range(0,len(images)): # print("正在下載"+str(count)+str(i)+"張圖片") # file=folder+str(count)+str(i)+".jpg" # urllib.request.urlretrieve(images[i],filename=file) else: #若是當前網址沒有圖片 跳過 pass except: #若是當前url寫不進數據庫,輸出異常 print("本網頁已經爬過了,跳過了哦") #打印提示 cursor.close() conn.close() return item
至此,代碼已經編寫完成 咱們來看看運行後是怎麼樣的dom