您好,登錄后才能下訂單哦!
目標網站:http://bbs.fengniao.com/
使用框架:scrapy
因為有很多模塊的方法都還不是很熟悉,所有本次爬蟲有很多代碼都用得比較笨,希望各位讀者能給處意見
首先創建好爬蟲項目,并使用crawl模板創建爬蟲文件
通過觀察論壇的規律得出,很多貼子的頁數往往大于一頁,那么要將貼子里各頁的圖片下載到同一文件夾內,并且不能重名,就是獲取到當前的頁碼數,已頁碼數+自然數的方式命令文件。
發現scrapy自動爬蟲會爬很多重復的頁面,度娘后得出兩個解決方法,第一個是用布隆過濾器,布隆過濾器相對于目前的我來說太過深奧,于是便采用了將URL寫入mysql的方式,通過mysql鍵的唯一性來去重復。
先編寫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("http://div[@class='img']//img/@src").extract() #獲取當前的圖片url
item["act"]=response.xpath("http://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
至此,代碼已經編寫完成 我們來看看運行后是怎么樣的
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。