#第一次使用Scrapy框架遇到很多坑,堅持去搜索,修改程式碼就可以解決問題。這次爬取的是一個鬥圖網站的最新表情圖片www.doutula.com/photo/list,練習使用Scrapy框架並且使用的隨機user agent防止被ban,鬥圖表情包每日更新,一共可以抓取5萬張左右的表情到硬碟中。為了節省時間我就抓了1萬多張。
Scrapy是一個為了爬取網站數據,提取結構性數據而寫的應用框架。 可以應用在包括資料挖掘,資訊處理或儲存歷史資料等一系列的程序中。
使用過程
建立一個Scrapy項目
定義提取的Item
編寫爬取網站的 spider 並提取 Item
#編寫 Item Pipeline 來儲存擷取的Item(即資料)
#接下來的圖表展現了Scrapy的架構,包括元件及在系統中發生的資料流的概覽(綠色箭頭所示)。 下面對每個組件都做了簡單介紹,並給出了詳細內容的連結。資料流如下所描述
元件
引擎負責控制資料流在系統中所有元件中流動,並在對應動作發生時觸發事件。 詳細內容查看下面的資料流(Data Flow)部分。
調度器從引擎接受request並將他們入隊,以便之後引擎請求他們時提供給引擎。
下載器負責取得頁面資料並提供給引擎,而後提供給spider。
Spider是Scrapy用戶編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類別。 每個spider負責處理一個特定(或一些)網站。 更多內容請看 Spiders 。
Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如訪問到資料庫中)。 更多內容可查看 Item Pipeline 。
下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response 。 其提供了一個簡單的機制,透過插入自訂程式碼來擴展Scrapy功能。更多內容請看 下載器中間件(Downloader Middleware) 。
Spider中間件是在引擎及Spider之間的特定鉤子(specific hook),處理spider的輸入(response)和輸出( items及requests)。 其提供了一個簡單的機制,透過插入自訂程式碼來擴展Scrapy功能。更多內容請看 Spider中間件(Middleware) 。
start_urls = ['https://www.doutula.com/photo/list/?page={}'.format(i) for i in range(1, 20)]2.進入開發者模式分析網頁結構,可以看到如下結構。右鍵複製一下xpath位址即可得到全部的表情所在的a標籤內容。 a[1]表示第一個a,去掉[1]就是全部的a。
//*[@id="pic-detail"]/div/div[1]/div[2]/a
#值得注意的是這裡的表情有兩種:一個jpg,一個gif動圖。如果取得圖片位址時只抓取a標籤下面第一個img的src就會出錯,所以我們要抓取img中的含有data-original的值。這裡a標籤下面還一個p標籤是圖片簡介,我們也抓取下來作為圖片檔的名稱。
图片的连接是 'http:' + content.xpath('//img/@data-original') 图片的名称是 content.xpath('//p/text()')
完整代码地址 github.com/rieuse/learnPython
1.首先使用命令行工具输入代码创建一个新的Scrapy项目,之后创建一个爬虫。
scrapy startproject ScrapyDoutu cd ScrapyDoutu\ScrapyDoutu\spidersscrapy genspider doutula doutula.com
2.打开Doutu文件夹中的items.py,改为以下代码,定义我们爬取的项目。
import scrapyclass DoutuItem(scrapy.Item): img_url = scrapy.Field() name = scrapy.Field()
3.打开spiders文件夹中的doutula.py,改为以下代码,这个是爬虫主程序。
# -*- coding: utf-8 -*- import os import scrapy import requestsfrom ScrapyDoutu.items import DoutuItems class Doutu(scrapy.Spider): name = "doutu" allowed_domains = ["doutula.com", "sinaimg.cn"] start_urls = ['https://www.doutula.com/photo/list/?page={}'.format(i) for i in range(1, 40)] # 我们暂且爬取40页图片 def parse(self, response): i = 0for content in response.xpath('//*[@id="pic-detail"]/div/div[1]/div[2]/a'): i += 1item = DoutuItems()item['img_url'] = 'http:' + content.xpath('//img/@data-original').extract()[i]item['name'] = content.xpath('//p/text()').extract()[i]try:if not os.path.exists('doutu'): os.makedirs('doutu') r = requests.get(item['img_url']) filename = 'doutu\\{}'.format(item['name']) + item['img_url'][-4:]with open(filename, 'wb') as fo: fo.write(r.content) except: print('Error') yield item
3.这里面有很多值得注意的部分:
因为图片的地址是放在sinaimg.cn中,所以要加入allowed_domains的列表中
content.xpath('//img/@data-original').extract()[i]
中extract()用来返回一个list(就是系统自带的那个) 里面是一些你提取的内容,[i]是结合前面的i的循环每次获取下一个标签内容,如果不这样设置,就会把全部的标签内容放入一个字典的值中。
filename = 'doutu\{}'.format(item['name']) + item['img_url'][-4:]
是用来获取图片的名称,最后item['img_url'][-4:]是获取图片地址的最后四位这样就可以保证不同的文件格式使用各自的后缀。
最后一点就是如果xpath没有正确匹配,则会出现64d8292994d119f5f1f87748047c90da (referer: None)
4.配置settings.py,如果想抓取快一点CONCURRENT_REQUESTS设置大一些,DOWNLOAD_DELAY设置小一些,或者为0.
# -*- coding: utf-8 -*-BOT_NAME = 'ScrapyDoutu'SPIDER_MODULES = ['ScrapyDoutu.spiders']NEWSPIDER_MODULE = 'ScrapyDoutu.spiders'DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, 'ScrapyDoutu.middlewares.RotateUserAgentMiddleware': 400, }ROBOTSTXT_OBEY = False # 不遵循网站的robots.txt策略CONCURRENT_REQUESTS = 16 #Scrapy downloader 并发请求(concurrent requests)的最大值DOWNLOAD_DELAY = 0.2 # 下载同一个网站页面前等待的时间,可以用来限制爬取速度减轻服务器压力。COOKIES_ENABLED = False # 关闭cookies
5.配置middleware.py配合settings中的UA设置可以在下载中随机选择UA有一定的反ban效果,在原有代码基础上加入下面代码。这里的user_agent_list可以加入更多。
import randomfrom scrapy.downloadermiddlewares.useragent import UserAgentMiddlewareclass RotateUserAgentMiddleware(UserAgentMiddleware): def __init__(self, user_agent=''): self.user_agent = user_agent def process_request(self, request, spider): ua = random.choice(self.user_agent_list) if ua: print(ua) request.headers.setdefault('User-Agent', ua) user_agent_list = [ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1" "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24" ]
6.到现在为止,代码都已经完成了。那么开始执行吧!scrapy crawl doutu
之后可以看到一边下载,一边修改User Agent。
学习使用Scrapy遇到很多坑,但是强大的搜索系统不会让我感觉孤单。所以感觉Scrapy还是很强大的也很意思,后面继续学习Scrapy的其他方面内容。
以上是如何抓取鬥圖網的最新表情圖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!