scrapy
從零開(kāi)始基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 412 次瀏覽 ? 2020-07-06 08:01
前節介紹了哪些網(wǎng)路爬蟲(chóng),什么是Scrapy框架并怎樣安裝
本節介紹基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
安裝好Scrapy框架后,就可以基于Scrapy框架開(kāi)發(fā)爬蟲(chóng)項目了?;诳蚣荛_(kāi)發(fā)項目,不需要從零開(kāi)始編撰代碼,只須要把握怎樣使用框架,如何添加與自己應用相關(guān)的代碼即可。
進(jìn)入準備新建爬蟲(chóng)項目的路徑中,使用命令:
scrapy startproject project_name
請用爬蟲(chóng)項目名稱(chēng)替換命令中的project_name爬蟲(chóng)軟件開(kāi)發(fā),例如,本文準備創(chuàng )建一個(gè)爬取新浪網(wǎng)的爬蟲(chóng),取名為sina_spider,則新建爬蟲(chóng)項目的命令為:
scrapy startproject sina_spider
命令運行結果,如下圖所示。
新建爬蟲(chóng)項目
“scrapy startproject sina_spider”命令會(huì )創(chuàng )建包含下述內容的sina_spider目錄,如圖13-5所示。
爬蟲(chóng)文件夾結構
新建好Scrapy爬蟲(chóng)項目后,接下來(lái)就是創(chuàng )建爬蟲(chóng)文件。請先步入sina_spider項目路徑,用命令:
scrapy genspider spider_filename(爬蟲(chóng)文件名) (待爬取的網(wǎng)站域名)
創(chuàng )建爬蟲(chóng)文件。例如,本文的爬蟲(chóng)文件名為:sinaSpider,待爬取的網(wǎng)站域名:,則創(chuàng )建爬蟲(chóng)文件sinaSpider的命令為:
scrapy genspider sinaSpider
現在好多網(wǎng)站都有防爬蟲(chóng)舉措,為了反網(wǎng)站的防爬蟲(chóng)舉措,需要添加user agent信息。請settings.py文件的第19行更改如下所示:
18. # Crawl responsibly by identifying yourself (and your website) on the user-agent
19. import random
20. # user agent 列表
21. USER_AGENT_LIST = [
22. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
23. "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
24. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
25. "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
26. "Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)",
27. "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
28. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0",
29. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0",
30. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0",
31. "Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)",
32. "Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)" ]
33. USER_AGENT = random.choice(USER_AGENT_LIST) # 隨機生成user agent
網(wǎng)站的服務(wù)器中保存一個(gè)robots.txt 文件,其作用是,告訴搜索引擎爬蟲(chóng),本網(wǎng)站哪些目錄下的網(wǎng)頁(yè)不希望被爬取收錄。Scrapy啟動(dòng)后,會(huì )在第一時(shí)間訪(fǎng)問(wèn)網(wǎng)站的 robots.txt 文件,然后決定該網(wǎng)站的爬取范圍。
由于本文的項目并非搜索引擎爬蟲(chóng),而且很有可能我們想要獲取的內容恰恰是被 robots.txt所嚴禁訪(fǎng)問(wèn)的,所以請把settings.py文件的ROBOTSTXT_OBEY值設置為False,表示拒絕遵循Robot合同,如下所示
1. # Obey robots.txt rules
2. ROBOTSTXT_OBEY = False # False表示拒絕遵守Robot協(xié)議
查看由Scrapy生成的sinaSpider.py文件,在SinaspiderSpider類(lèi)中,有一個(gè)parse()方法須要用戶(hù)編撰,如下圖所示
編寫(xiě)parse()方法
Scrapy框架把爬取出來(lái)的網(wǎng)頁(yè)源代碼儲存在response對象中爬蟲(chóng)軟件開(kāi)發(fā),我們只須要對response對象中的網(wǎng)頁(yè)源代碼做解析,提取想要的數據即可。本范例目標是抓取新浪網(wǎng)頁(yè)的新聞的標題和對應的鏈接,如下圖所示。
HTML源代碼
parse()方法的實(shí)現代碼,如下所示
1. # -*- coding: utf-8 -*-
2. import scrapy
3.
4. class SinaspiderSpider(scrapy.Spider):
5. name = 'sinaSpider'
6. allowed_domains = ['www.sina.com.cn']
7. start_urls = ['http://www.sina.com.cn/']
8.
9. def parse(self, response):
10. data_list = [] #用于存儲解析到的數據
11. #解析HTML源代碼,定位新聞內容
12. lis = response.xpath("//div[@class='top_newslist']/ul[@class='list-a news_top']//li")
13. #將新聞主題和超鏈接解析出來(lái)并整理到列表中
14. for li in lis:
15. titles = li.xpath(".//a/text()")
16. linkes = li.xpath(".//a/@href")
17. for title, link in zip(titles, linkes):
18. #將新聞主題和對應的超鏈接組合成字典
19. data_dict = {'標題': title.extract(), '鏈接': link.extract()}
20. #將字典數據存儲到data_list這個(gè)列表中
21. data_list.append(data_dict)
22. return data_list
parse()方法在解析HTML源代碼時(shí),使用了XPath路徑表達式。XPath是一門(mén)在HTML/XML文檔中查找信息的語(yǔ)言,常用于在網(wǎng)頁(yè)HTML源代碼中,查找特定標簽里的數據。在網(wǎng)絡(luò )爬蟲(chóng)中使用XPath,只須要把握 XPath路徑表達式即可。XPath 使用路徑表達式來(lái)選定 HTML/XML文檔中的節點(diǎn)或則節點(diǎn)集。
parse()方法編撰好后,就可以運行爬蟲(chóng)程序并保存抓取數據了。用命令:
scrapy crawl 爬蟲(chóng)文件名 –o 保存數據文件名.[csv|json|xml]
保存數據的文件格式可以是csv 或 json 或 xml,本例的爬蟲(chóng)文件名為:sinaSpider.py,數據儲存選擇csv格式,命令為:
scrapy crawl sinaSpider -o sinaNews.csv
運行療效,如下圖所示
運行爬蟲(chóng)
到此,本例基于Scrapy框架從零開(kāi)始實(shí)現了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)程序,爬取了新浪網(wǎng)頁(yè)并從中解析出新聞的標題和對應的超鏈接,最后把解析出的數據保存為csv文件供后續使用。 查看全部

前節介紹了哪些網(wǎng)路爬蟲(chóng),什么是Scrapy框架并怎樣安裝
本節介紹基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
安裝好Scrapy框架后,就可以基于Scrapy框架開(kāi)發(fā)爬蟲(chóng)項目了?;诳蚣荛_(kāi)發(fā)項目,不需要從零開(kāi)始編撰代碼,只須要把握怎樣使用框架,如何添加與自己應用相關(guān)的代碼即可。
進(jìn)入準備新建爬蟲(chóng)項目的路徑中,使用命令:
scrapy startproject project_name
請用爬蟲(chóng)項目名稱(chēng)替換命令中的project_name爬蟲(chóng)軟件開(kāi)發(fā),例如,本文準備創(chuàng )建一個(gè)爬取新浪網(wǎng)的爬蟲(chóng),取名為sina_spider,則新建爬蟲(chóng)項目的命令為:
scrapy startproject sina_spider
命令運行結果,如下圖所示。

新建爬蟲(chóng)項目
“scrapy startproject sina_spider”命令會(huì )創(chuàng )建包含下述內容的sina_spider目錄,如圖13-5所示。

爬蟲(chóng)文件夾結構
新建好Scrapy爬蟲(chóng)項目后,接下來(lái)就是創(chuàng )建爬蟲(chóng)文件。請先步入sina_spider項目路徑,用命令:
scrapy genspider spider_filename(爬蟲(chóng)文件名) (待爬取的網(wǎng)站域名)
創(chuàng )建爬蟲(chóng)文件。例如,本文的爬蟲(chóng)文件名為:sinaSpider,待爬取的網(wǎng)站域名:,則創(chuàng )建爬蟲(chóng)文件sinaSpider的命令為:
scrapy genspider sinaSpider
現在好多網(wǎng)站都有防爬蟲(chóng)舉措,為了反網(wǎng)站的防爬蟲(chóng)舉措,需要添加user agent信息。請settings.py文件的第19行更改如下所示:
18. # Crawl responsibly by identifying yourself (and your website) on the user-agent
19. import random
20. # user agent 列表
21. USER_AGENT_LIST = [
22. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
23. "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
24. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
25. "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
26. "Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)",
27. "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
28. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0",
29. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0",
30. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0",
31. "Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)",
32. "Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)" ]
33. USER_AGENT = random.choice(USER_AGENT_LIST) # 隨機生成user agent
網(wǎng)站的服務(wù)器中保存一個(gè)robots.txt 文件,其作用是,告訴搜索引擎爬蟲(chóng),本網(wǎng)站哪些目錄下的網(wǎng)頁(yè)不希望被爬取收錄。Scrapy啟動(dòng)后,會(huì )在第一時(shí)間訪(fǎng)問(wèn)網(wǎng)站的 robots.txt 文件,然后決定該網(wǎng)站的爬取范圍。
由于本文的項目并非搜索引擎爬蟲(chóng),而且很有可能我們想要獲取的內容恰恰是被 robots.txt所嚴禁訪(fǎng)問(wèn)的,所以請把settings.py文件的ROBOTSTXT_OBEY值設置為False,表示拒絕遵循Robot合同,如下所示
1. # Obey robots.txt rules
2. ROBOTSTXT_OBEY = False # False表示拒絕遵守Robot協(xié)議
查看由Scrapy生成的sinaSpider.py文件,在SinaspiderSpider類(lèi)中,有一個(gè)parse()方法須要用戶(hù)編撰,如下圖所示

編寫(xiě)parse()方法
Scrapy框架把爬取出來(lái)的網(wǎng)頁(yè)源代碼儲存在response對象中爬蟲(chóng)軟件開(kāi)發(fā),我們只須要對response對象中的網(wǎng)頁(yè)源代碼做解析,提取想要的數據即可。本范例目標是抓取新浪網(wǎng)頁(yè)的新聞的標題和對應的鏈接,如下圖所示。

HTML源代碼
parse()方法的實(shí)現代碼,如下所示
1. # -*- coding: utf-8 -*-
2. import scrapy
3.
4. class SinaspiderSpider(scrapy.Spider):
5. name = 'sinaSpider'
6. allowed_domains = ['www.sina.com.cn']
7. start_urls = ['http://www.sina.com.cn/']
8.
9. def parse(self, response):
10. data_list = [] #用于存儲解析到的數據
11. #解析HTML源代碼,定位新聞內容
12. lis = response.xpath("//div[@class='top_newslist']/ul[@class='list-a news_top']//li")
13. #將新聞主題和超鏈接解析出來(lái)并整理到列表中
14. for li in lis:
15. titles = li.xpath(".//a/text()")
16. linkes = li.xpath(".//a/@href")
17. for title, link in zip(titles, linkes):
18. #將新聞主題和對應的超鏈接組合成字典
19. data_dict = {'標題': title.extract(), '鏈接': link.extract()}
20. #將字典數據存儲到data_list這個(gè)列表中
21. data_list.append(data_dict)
22. return data_list
parse()方法在解析HTML源代碼時(shí),使用了XPath路徑表達式。XPath是一門(mén)在HTML/XML文檔中查找信息的語(yǔ)言,常用于在網(wǎng)頁(yè)HTML源代碼中,查找特定標簽里的數據。在網(wǎng)絡(luò )爬蟲(chóng)中使用XPath,只須要把握 XPath路徑表達式即可。XPath 使用路徑表達式來(lái)選定 HTML/XML文檔中的節點(diǎn)或則節點(diǎn)集。
parse()方法編撰好后,就可以運行爬蟲(chóng)程序并保存抓取數據了。用命令:
scrapy crawl 爬蟲(chóng)文件名 –o 保存數據文件名.[csv|json|xml]
保存數據的文件格式可以是csv 或 json 或 xml,本例的爬蟲(chóng)文件名為:sinaSpider.py,數據儲存選擇csv格式,命令為:
scrapy crawl sinaSpider -o sinaNews.csv
運行療效,如下圖所示

運行爬蟲(chóng)
到此,本例基于Scrapy框架從零開(kāi)始實(shí)現了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)程序,爬取了新浪網(wǎng)頁(yè)并從中解析出新聞的標題和對應的超鏈接,最后把解析出的數據保存為csv文件供后續使用。
爬蟲(chóng)框架(scrapy構架)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 588 次瀏覽 ? 2020-07-03 08:00
scrapy主要包括了以下組件: 1.)引擎(scrapy):用來(lái)處理整個(gè)系統的數據流,觸發(fā)事務(wù)(框架核心) 2.)調度器(Scheduler):用來(lái)接受引擎發(fā)過(guò)來(lái)的懇求,壓入隊列中,并在引擎再度懇求的時(shí)侯返回,可以想像成一個(gè)url(抓取網(wǎng)頁(yè)的網(wǎng)址或則說(shuō)鏈接)的優(yōu)先隊列,由它來(lái)決定下一個(gè)要抓取的網(wǎng)址是哪些,同時(shí)除去重復的網(wǎng)址。 3.)下載器(Downloader):用于下載網(wǎng)頁(yè)的內容,并將網(wǎng)頁(yè)內容返回給蜘蛛(Scrapy下載器是構建在twisted這個(gè)高效的異步模型上的) 4.)爬蟲(chóng)(Spiders):爬蟲(chóng)是主要干活的,用于從特定的網(wǎng)頁(yè)中提取自己想要的信息,即所謂的實(shí)體(item)。用戶(hù)也可以從中提取到鏈接,讓Scrapy繼續抓取下一個(gè)頁(yè)面。 5.)項目管線(xiàn)(Pipeline):負責處理爬蟲(chóng)從網(wǎng)頁(yè)中抽取的實(shí)體,主要的功能是持久化實(shí)體、清除不需要的信息。當頁(yè)面被爬蟲(chóng)解析后,將被發(fā)送到項目管線(xiàn),并經(jīng)過(guò)幾個(gè)特定的順序處理數據。 (只有當調度器中不存在任何request時(shí),整個(gè)程序就會(huì )停止。(對于下載失敗的url,Scrapy也會(huì )重新下載))
前置要求: pip下載scrapy模塊 yum下載tree包
-確定url地址; -獲取頁(yè)面信息;(urllib,requests) -解析頁(yè)面提取須要的信息;(xpath,bs4,正則表達時(shí)) -保存到本地(scv,json,pymysql,redis) -清洗數據(刪除不必要的內容------正則表達式) -分析數據(詞云wordcloud,jieba)
-確定url地址(spider) -獲取頁(yè)面信息(Downloader) -解析頁(yè)面提取須要的信息(spider) -保存到本地(pipeline)
scrapy1.6.0
1.工程創(chuàng )建 1.)命令行在當前目錄下創(chuàng )建mySpider
scrapy startproject mySpider
2.)創(chuàng )建成功后,進(jìn)入mySpider ,tree查看
cd mySpider tree
2.創(chuàng )建一個(gè)爬蟲(chóng)
#scrapy genspider 項目名 url scrapy genspider mooc ‘’
3.定義爬取的items內容(items.py)
class CourseItem(scrapy.Item):
#課程標題 title=scrapy.Field() #課程的url地址 url=scrapy.Field() #課程圖片的url地址 image_url=scrapy.Field() #課程的描述 introduction=scrapy.Field() #學(xué)習人數 student=scrapy.Field()
4.編寫(xiě)spider代碼,解析 4.1確定url地址,提取頁(yè)面須要的信息(mooc.py)
class MoocSpider(scrapy,spider):
#name用于區別爬蟲(chóng),必須惟一 name=‘mooc’ #允許爬取的域名,其他網(wǎng)站的頁(yè)面直接跳過(guò) allowd_domains=[‘’,‘’] #爬蟲(chóng)開(kāi)啟時(shí)第一個(gè)裝入調度器的url地址 start_urls=[‘’] #被調用時(shí),每個(gè)新的url完成下載后爬蟲(chóng)框架,返回一個(gè)響應對象 #下面的方式負責將響應的數據剖析,提取出須要的數據items以及生成下一步須要處理的url地址懇求; def parser(self,response):
##用來(lái)檢查代碼是否達到指定位置,并拿來(lái)調試并解析頁(yè)面信息; #from scrapy.shell import inspect_response #inspect_response(response,self) #1.)實(shí)例化對象,CourseItem course=CourseItem() #分析響應的內容 #scrapy剖析頁(yè)面使用的是xpath方式 #2.)獲取每位課程的信息 courseDetails=course.xpath(’.//div[@class=“course-card-container”]’) for courseDetail in courseDetails:
#爬取新的網(wǎng)站, Scrapy上面進(jìn)行調試(parse命令logging) course[‘title’] = courseDetail.xpath(’.//h3[@class=“course-card-name”]/text()’).extract()[0] #學(xué)習人數 course[‘student’] = courseDetail.xpath(’.//span/text()’).extract()[1] #課程描述: course[‘introduction’] = courseDetail.xpath(".//p[@class=‘course-card-desc’]/text()").extract()[0] #課程鏈接, h獲取/learn/9 ====》 course[‘url’] = “” + courseDetail.xpath(’.//a/@href’).extract()[0] #課程的圖片url: course[‘image_url’] = ‘http:’ + courseDetail.xpath(’.//img/@src’).extract()[0] yield course #url跟進(jìn),獲取下一步是否有鏈接;href url=response.xpath(’.//a[contains[text(),“下一頁(yè)”]/@href’)[0].extract() if url:
#構建新的url page=‘’+url yield scrapy.Request(page,callback=slef.parse)
4.2保存我們提取的信息(文件格式:scv爬蟲(chóng)框架,json,pymysql)(pipeline.py) 如果多線(xiàn)程,記得在settings.py中分配多個(gè)管線(xiàn)并設置優(yōu)先級:
(1).將爬取的信息保存成json格式
class MyspiderPipeline(object):
def init(self):
self.f=open(Moocfilename,‘w’) #Moocfilename是寫(xiě)在settings.py里的文件名,寫(xiě)在setting.py是因為便捷更改
def process_item(self,item,spider):
#默認傳過(guò)來(lái)的格式是json格式 import json #讀取item中的數據,并轉化為json格式 line=json.dumps(dict(item),ensure_ascii=False,indent=4) self.f.write(line+’\n’) #一定要返回給調度器 return item
def close_spider(self,spider):
self.f.close()
(2).保存為scv格式
class CsvPipeline(object):
def init(self):
self.f=open(’'mooc.csv",‘w’)
def process_item(self,item,spider):
item=dict(item) self.f.write("{0}:{1}:{2}\n".format(item[‘title’] , item[‘student’] , item[‘url’])) return item
def close_spider(self,spider):
self.f.close()
(3).將爬取的信息保存到數據庫中 首先打開(kāi)數據庫創(chuàng )建mooc表
class MysqlPipeline(object):
def init(self):
self.conn=pymysql.connect( host=‘localhost’, user=‘root’, password=‘redhat’, db=‘Mooc’, charset=‘utf8’, ) self.cursor=self.conn.cursor()
def process_item(self,item,spider):
item=dict(item) info=(item[’‘item"] , item[“url”] , item[“image_url”] , item[“introduction”] , item[“student”]) insert_sqil="insert into moocinfo values(’%s’ , ‘%s’ , ‘%s’, ‘%s’ , ‘%s’); " %(info) self.cursor.execute(insert_sqil) mit() return item
def open_spider(self,spider):
create_sqli=“create table if not exists moocinfo (title varchar(50),url varchar(200), image_url varchar(200), introduction varchar(500), student int)” self.cursor.execute(create_sqli)
def close_spider(self,spider):
self.cursor.close() self.conn.close()
(4).通過(guò)爬取的圖片鏈接下載圖片
class ImagePipeline(object):
def get_media_requests(self,item,info):
#返回一個(gè)request請求,包含圖片的url
yield scrapy.Request(item['image_url'])
def item_conpleted(self,results,item,info):
#獲取下載的地址
image_xpath=[x['path'] for ok , x in results if ok]
if not image_path:
raise Exception('不包含圖片')
else:
return item
1.策略一:設置download_delay –作用:設置下載的等待時(shí)間,大規模集中的訪(fǎng)問(wèn)對服務(wù)器的影響最大,相當于短時(shí)間內減小服務(wù)器的負載 –缺點(diǎn):下載等待時(shí)間長(cháng),不能滿(mǎn)足段時(shí)間大規模抓取的要求,太短則大大降低了被ban的機率
2.策略二:禁止cookies –cookie有時(shí)也用作復數方式cookies,指個(gè)別網(wǎng)站為了分辨用戶(hù)的身分,進(jìn)行session跟蹤而存儲在用戶(hù)本地終端上的數據(通常經(jīng)過(guò)加密)。 –作用:禁止cookies也就避免了可能使用cookies辨識爬蟲(chóng)軌跡的網(wǎng)站得逞 –實(shí)現:COOKIES_ENABLES=False
3.策略三:使用user_agent池(拓展:用戶(hù)代理中間件) –為什么要使用?scrapy本身是使用Scrapy/0.22.2來(lái)表明自己的身分。這也就曝露了自己是爬蟲(chóng)的信息。 –user agent ,是指包含瀏覽器信息,操作系統信息等的一個(gè)字符串,也稱(chēng)之為一種特殊的網(wǎng)路合同。服務(wù)器通過(guò)它判定當前的訪(fǎng)問(wèn)對象是瀏覽器,郵件客戶(hù)端還是爬蟲(chóng)。
4.策略四:使用代理中間件 –web server應對爬蟲(chóng)的策略之一就是直接將你的ip或則是整個(gè)ip段都封掉嚴禁訪(fǎng)問(wèn),這時(shí)候,當ip封掉后,轉換到其他的ip繼續訪(fǎng)問(wèn)即可。
5.策略五:分布式爬蟲(chóng)Scrapy+redis+mysql # 多進(jìn)程 –Scrapy-Redis則是一個(gè)基于Redis的Scrapy分布式組件。它借助Redis對用于爬取的懇求(Requests)進(jìn)行儲存和調度(Schedule),并對爬取形成rapy一些比較關(guān)鍵的代碼,將Scrapy弄成一個(gè)可以在多個(gè)主機上同時(shí)運行的分布式爬蟲(chóng)。
米鼠網(wǎng)自創(chuàng )立以來(lái)仍然專(zhuān)注于從事政府采購、軟件項目、人才外包、獵頭服務(wù)、綜合項目等,始終秉持“專(zhuān)業(yè)的服務(wù),易用的產(chǎn)品”的經(jīng)營(yíng)理念,以“提供高品質(zhì)的服務(wù)、滿(mǎn)足顧客的需求、攜手共創(chuàng )多贏(yíng)”為企業(yè)目標,為中國境內企業(yè)提供國際化、專(zhuān)業(yè)化、個(gè)性化、的軟件項目解決方案,我司擁有一流的項目總監團隊,具備過(guò)硬的軟件項目設計和施行能力,為全省不同行業(yè)顧客提供優(yōu)質(zhì)的產(chǎn)品和服務(wù),得到了顧客的廣泛贊揚。
如有侵權請聯(lián)系郵箱() 查看全部
1.scrapy構架流程:

scrapy主要包括了以下組件: 1.)引擎(scrapy):用來(lái)處理整個(gè)系統的數據流,觸發(fā)事務(wù)(框架核心) 2.)調度器(Scheduler):用來(lái)接受引擎發(fā)過(guò)來(lái)的懇求,壓入隊列中,并在引擎再度懇求的時(shí)侯返回,可以想像成一個(gè)url(抓取網(wǎng)頁(yè)的網(wǎng)址或則說(shuō)鏈接)的優(yōu)先隊列,由它來(lái)決定下一個(gè)要抓取的網(wǎng)址是哪些,同時(shí)除去重復的網(wǎng)址。 3.)下載器(Downloader):用于下載網(wǎng)頁(yè)的內容,并將網(wǎng)頁(yè)內容返回給蜘蛛(Scrapy下載器是構建在twisted這個(gè)高效的異步模型上的) 4.)爬蟲(chóng)(Spiders):爬蟲(chóng)是主要干活的,用于從特定的網(wǎng)頁(yè)中提取自己想要的信息,即所謂的實(shí)體(item)。用戶(hù)也可以從中提取到鏈接,讓Scrapy繼續抓取下一個(gè)頁(yè)面。 5.)項目管線(xiàn)(Pipeline):負責處理爬蟲(chóng)從網(wǎng)頁(yè)中抽取的實(shí)體,主要的功能是持久化實(shí)體、清除不需要的信息。當頁(yè)面被爬蟲(chóng)解析后,將被發(fā)送到項目管線(xiàn),并經(jīng)過(guò)幾個(gè)特定的順序處理數據。 (只有當調度器中不存在任何request時(shí),整個(gè)程序就會(huì )停止。(對于下載失敗的url,Scrapy也會(huì )重新下載))
前置要求: pip下載scrapy模塊 yum下載tree包
-確定url地址; -獲取頁(yè)面信息;(urllib,requests) -解析頁(yè)面提取須要的信息;(xpath,bs4,正則表達時(shí)) -保存到本地(scv,json,pymysql,redis) -清洗數據(刪除不必要的內容------正則表達式) -分析數據(詞云wordcloud,jieba)
-確定url地址(spider) -獲取頁(yè)面信息(Downloader) -解析頁(yè)面提取須要的信息(spider) -保存到本地(pipeline)
scrapy1.6.0
1.工程創(chuàng )建 1.)命令行在當前目錄下創(chuàng )建mySpider
scrapy startproject mySpider
2.)創(chuàng )建成功后,進(jìn)入mySpider ,tree查看
cd mySpider tree

2.創(chuàng )建一個(gè)爬蟲(chóng)
#scrapy genspider 項目名 url scrapy genspider mooc ‘’
3.定義爬取的items內容(items.py)
class CourseItem(scrapy.Item):
#課程標題 title=scrapy.Field() #課程的url地址 url=scrapy.Field() #課程圖片的url地址 image_url=scrapy.Field() #課程的描述 introduction=scrapy.Field() #學(xué)習人數 student=scrapy.Field()
4.編寫(xiě)spider代碼,解析 4.1確定url地址,提取頁(yè)面須要的信息(mooc.py)
class MoocSpider(scrapy,spider):
#name用于區別爬蟲(chóng),必須惟一 name=‘mooc’ #允許爬取的域名,其他網(wǎng)站的頁(yè)面直接跳過(guò) allowd_domains=[‘’,‘’] #爬蟲(chóng)開(kāi)啟時(shí)第一個(gè)裝入調度器的url地址 start_urls=[‘’] #被調用時(shí),每個(gè)新的url完成下載后爬蟲(chóng)框架,返回一個(gè)響應對象 #下面的方式負責將響應的數據剖析,提取出須要的數據items以及生成下一步須要處理的url地址懇求; def parser(self,response):
##用來(lái)檢查代碼是否達到指定位置,并拿來(lái)調試并解析頁(yè)面信息; #from scrapy.shell import inspect_response #inspect_response(response,self) #1.)實(shí)例化對象,CourseItem course=CourseItem() #分析響應的內容 #scrapy剖析頁(yè)面使用的是xpath方式 #2.)獲取每位課程的信息 courseDetails=course.xpath(’.//div[@class=“course-card-container”]’) for courseDetail in courseDetails:
#爬取新的網(wǎng)站, Scrapy上面進(jìn)行調試(parse命令logging) course[‘title’] = courseDetail.xpath(’.//h3[@class=“course-card-name”]/text()’).extract()[0] #學(xué)習人數 course[‘student’] = courseDetail.xpath(’.//span/text()’).extract()[1] #課程描述: course[‘introduction’] = courseDetail.xpath(".//p[@class=‘course-card-desc’]/text()").extract()[0] #課程鏈接, h獲取/learn/9 ====》 course[‘url’] = “” + courseDetail.xpath(’.//a/@href’).extract()[0] #課程的圖片url: course[‘image_url’] = ‘http:’ + courseDetail.xpath(’.//img/@src’).extract()[0] yield course #url跟進(jìn),獲取下一步是否有鏈接;href url=response.xpath(’.//a[contains[text(),“下一頁(yè)”]/@href’)[0].extract() if url:
#構建新的url page=‘’+url yield scrapy.Request(page,callback=slef.parse)
4.2保存我們提取的信息(文件格式:scv爬蟲(chóng)框架,json,pymysql)(pipeline.py) 如果多線(xiàn)程,記得在settings.py中分配多個(gè)管線(xiàn)并設置優(yōu)先級:

(1).將爬取的信息保存成json格式
class MyspiderPipeline(object):
def init(self):
self.f=open(Moocfilename,‘w’) #Moocfilename是寫(xiě)在settings.py里的文件名,寫(xiě)在setting.py是因為便捷更改
def process_item(self,item,spider):
#默認傳過(guò)來(lái)的格式是json格式 import json #讀取item中的數據,并轉化為json格式 line=json.dumps(dict(item),ensure_ascii=False,indent=4) self.f.write(line+’\n’) #一定要返回給調度器 return item
def close_spider(self,spider):
self.f.close()
(2).保存為scv格式
class CsvPipeline(object):
def init(self):
self.f=open(’'mooc.csv",‘w’)
def process_item(self,item,spider):
item=dict(item) self.f.write("{0}:{1}:{2}\n".format(item[‘title’] , item[‘student’] , item[‘url’])) return item
def close_spider(self,spider):
self.f.close()
(3).將爬取的信息保存到數據庫中 首先打開(kāi)數據庫創(chuàng )建mooc表
class MysqlPipeline(object):
def init(self):
self.conn=pymysql.connect( host=‘localhost’, user=‘root’, password=‘redhat’, db=‘Mooc’, charset=‘utf8’, ) self.cursor=self.conn.cursor()
def process_item(self,item,spider):
item=dict(item) info=(item[’‘item"] , item[“url”] , item[“image_url”] , item[“introduction”] , item[“student”]) insert_sqil="insert into moocinfo values(’%s’ , ‘%s’ , ‘%s’, ‘%s’ , ‘%s’); " %(info) self.cursor.execute(insert_sqil) mit() return item
def open_spider(self,spider):
create_sqli=“create table if not exists moocinfo (title varchar(50),url varchar(200), image_url varchar(200), introduction varchar(500), student int)” self.cursor.execute(create_sqli)
def close_spider(self,spider):
self.cursor.close() self.conn.close()
(4).通過(guò)爬取的圖片鏈接下載圖片
class ImagePipeline(object):
def get_media_requests(self,item,info):
#返回一個(gè)request請求,包含圖片的url
yield scrapy.Request(item['image_url'])
def item_conpleted(self,results,item,info):
#獲取下載的地址
image_xpath=[x['path'] for ok , x in results if ok]
if not image_path:
raise Exception('不包含圖片')
else:
return item
1.策略一:設置download_delay –作用:設置下載的等待時(shí)間,大規模集中的訪(fǎng)問(wèn)對服務(wù)器的影響最大,相當于短時(shí)間內減小服務(wù)器的負載 –缺點(diǎn):下載等待時(shí)間長(cháng),不能滿(mǎn)足段時(shí)間大規模抓取的要求,太短則大大降低了被ban的機率
2.策略二:禁止cookies –cookie有時(shí)也用作復數方式cookies,指個(gè)別網(wǎng)站為了分辨用戶(hù)的身分,進(jìn)行session跟蹤而存儲在用戶(hù)本地終端上的數據(通常經(jīng)過(guò)加密)。 –作用:禁止cookies也就避免了可能使用cookies辨識爬蟲(chóng)軌跡的網(wǎng)站得逞 –實(shí)現:COOKIES_ENABLES=False
3.策略三:使用user_agent池(拓展:用戶(hù)代理中間件) –為什么要使用?scrapy本身是使用Scrapy/0.22.2來(lái)表明自己的身分。這也就曝露了自己是爬蟲(chóng)的信息。 –user agent ,是指包含瀏覽器信息,操作系統信息等的一個(gè)字符串,也稱(chēng)之為一種特殊的網(wǎng)路合同。服務(wù)器通過(guò)它判定當前的訪(fǎng)問(wèn)對象是瀏覽器,郵件客戶(hù)端還是爬蟲(chóng)。
4.策略四:使用代理中間件 –web server應對爬蟲(chóng)的策略之一就是直接將你的ip或則是整個(gè)ip段都封掉嚴禁訪(fǎng)問(wèn),這時(shí)候,當ip封掉后,轉換到其他的ip繼續訪(fǎng)問(wèn)即可。
5.策略五:分布式爬蟲(chóng)Scrapy+redis+mysql # 多進(jìn)程 –Scrapy-Redis則是一個(gè)基于Redis的Scrapy分布式組件。它借助Redis對用于爬取的懇求(Requests)進(jìn)行儲存和調度(Schedule),并對爬取形成rapy一些比較關(guān)鍵的代碼,將Scrapy弄成一個(gè)可以在多個(gè)主機上同時(shí)運行的分布式爬蟲(chóng)。
米鼠網(wǎng)自創(chuàng )立以來(lái)仍然專(zhuān)注于從事政府采購、軟件項目、人才外包、獵頭服務(wù)、綜合項目等,始終秉持“專(zhuān)業(yè)的服務(wù),易用的產(chǎn)品”的經(jīng)營(yíng)理念,以“提供高品質(zhì)的服務(wù)、滿(mǎn)足顧客的需求、攜手共創(chuàng )多贏(yíng)”為企業(yè)目標,為中國境內企業(yè)提供國際化、專(zhuān)業(yè)化、個(gè)性化、的軟件項目解決方案,我司擁有一流的項目總監團隊,具備過(guò)硬的軟件項目設計和施行能力,為全省不同行業(yè)顧客提供優(yōu)質(zhì)的產(chǎn)品和服務(wù),得到了顧客的廣泛贊揚。

如有侵權請聯(lián)系郵箱()
基于Scrapy框架的分布式網(wǎng)路爬蟲(chóng)實(shí)現
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 279 次瀏覽 ? 2020-05-14 08:09
2.2 用戶(hù)登入 由于網(wǎng)站對于旅客的訪(fǎng)問(wèn)有限制,為了爬取所需信息,必須在程序中實(shí)現用戶(hù)登陸,其原 理就是能獲取到有效的本地 cookie,并借助該 cookie 進(jìn)行網(wǎng)站訪(fǎng)問(wèn),除了通常還能用第三方庫 進(jìn)行圖象辨識的驗證方法外,一般采用瀏覽器中自動(dòng)登入,通過(guò)網(wǎng)路工具截取有效的 cookie, 然后在爬蟲(chóng)生成 request 時(shí)附送上 cookie。 2.3 url 的去重 龍源期刊網(wǎng) scrapy_redis 有一個(gè) dupefilter 文件中包含 RFPDupeFilter 類(lèi)用于過(guò)濾新增的 url,可以在該 類(lèi) request_seen 中借助 redis 的 key 的查找功能,如果所爬取的任務(wù)數以?xún)|計則建議 Bloomfilter 去重的方法對于 URL 的儲存和操作方法進(jìn)行優(yōu)化,雖然該方法會(huì )導致大于萬(wàn)分之一的過(guò)濾遺 失率。 2.4 數據寫(xiě)入 選擇非關(guān)系性數據庫 MongoDB 作為硬碟數據庫與 scrapy 進(jìn)行搭配使用,在 pipeline 中對 item 數據進(jìn)行 MongoDB 的寫(xiě)入操作。 3 基本實(shí)現步驟 配置:Windows7 64-bit、Python:2.7.11、 Anaconda 4.0.0 (64-bit)、IDE:Pycharm 3.4.1、Scrapy:1.3.2Redis:X64-3.2、MongoDB:3.2.12 代碼實(shí)現須要對幾個(gè)文件進(jìn)行設置和編撰:items、settings、spiders、pipelines。
Items:這是一個(gè)爬取數據的基礎數據結構類(lèi),由其來(lái)儲存爬蟲(chóng)爬取的鍵值性數據,關(guān)鍵 的就是這條句子:_id = Field() _id 表示的生成一個(gè)數據對象,在 Items 中可以按照須要設定 多個(gè)數據對象。 Settings:ITEM_PIPELINES 該參數決定了 item 的處理方式;DOWNLOAD_DELAY 這個(gè) 是下載的間隔時(shí)間;SCHEDULER 指定作為總的任務(wù)協(xié)調器的類(lèi); SCHEDULER_QUEUE_CLASS 這個(gè)參數是設定處理 URL 的隊列的工作模式一共有四種,一般 選用 SpiderSimpleQueue 即可。 spiders:該文件就是爬蟲(chóng)主要功能的實(shí)現,首先設定該爬蟲(chóng)的基本信息:name、domain、 redis_key、start_urls。爬蟲(chóng)的第一步都是執行方式 start_requests,其中核心句子 yield Request (url,callback)用以按照 url 產(chǎn)生一個(gè) request 并且將 response 結果回傳給 callback 方法。 callback 的方式中通常借助 xpath 或者正則表達式對 response 中包含的 html 代碼進(jìn)行解析,產(chǎn) 生所須要的數據以及新的任務(wù) url。
pipelines:該文件作為數據處理、存儲的代碼段分布式爬蟲(chóng)框架,將在 items 數據被創(chuàng )建后被調用,其中 process_item 的方式就是被調用的方式,所以一定要將其重畫(huà),根據實(shí)際須要把數據借助方式 dict()轉化為字典數據,最后寫(xiě)入 MongoDB。 完成編撰后,在布署的時(shí)侯,start_url 的隊列只能是第一個(gè)運行的爬蟲(chóng)進(jìn)行初始化,后續 運行的爬蟲(chóng)只能是把新的 url 進(jìn)行寫(xiě)入不能對其進(jìn)行再度初始化,部署爬蟲(chóng)的步驟也很簡(jiǎn)單, 只須要把相關(guān)的代碼拷貝到目標筆記本上,讓后 cmd 命令步入 spiders 的文件夾,運行命令 scrapy crawl XXXX,其中 XXXX 就是爬蟲(chóng)的名子,就完成了爬蟲(chóng)的布署和運行了。 龍源期刊網(wǎng) 4 結語(yǔ) 爬蟲(chóng)的實(shí)現,除了基本的步驟和參數設置之外,需要開(kāi)發(fā)者按照實(shí)際網(wǎng)站以及數據情況, 針對性的對爬取的策略、數據的去重、數據篩選進(jìn)行處理,對于爬蟲(chóng)的性能進(jìn)行有效優(yōu)化,為 之后的數據剖析做好良好的數據打算。同時(shí),根據須要可以考慮時(shí)間的誘因加入到數據結構 中,這就要求爬蟲(chóng)還能通過(guò)數據的時(shí)間去進(jìn)行增量爬取。 參考文獻 [1]使用 redis 如何實(shí)現一個(gè)網(wǎng)絡(luò )分布式爬蟲(chóng)[OL].http: //www.oschina.net/code/snippet_209440_20495/. [2]scrapy_redis 的使用解讀[OL].http://www.cnblogs.com/kylinlin/p/5198233.html.http: //blog.csdn.net/u012150179/art 查看全部
龍源期刊網(wǎng) 基于 Scrapy 框架的分布式網(wǎng)路爬蟲(chóng)實(shí)現 作者:陶興海 來(lái)源:《電子技術(shù)與軟件工程》2017 年第 11 期 摘 要按照互聯(lián)網(wǎng)實(shí)際情況,提出分布式爬蟲(chóng)模型,基于 Scrapy 框架,進(jìn)行代碼實(shí)現,且 該開(kāi)發(fā)方法可以迅速進(jìn)行對不同主題的數據爬取的移植,滿(mǎn)足不同專(zhuān)業(yè)方向的基于互聯(lián)網(wǎng)大數 據剖析須要。 【關(guān)鍵詞】網(wǎng)絡(luò )爬蟲(chóng) Scrapy-redis 分布式 1 基本概念 分布式爬蟲(chóng):分布式方法是以共同爬取為目標,形成多爬蟲(chóng)協(xié)同工作的模式,每個(gè)爬蟲(chóng)需 要獨立完成單項爬取任務(wù),下載網(wǎng)頁(yè)并保存。 Scrapy-redis:一個(gè)三方的基于 redis 數據庫實(shí)現的分布式方法,配合 scrapy 爬蟲(chóng)框架讓 用,讓 scrapy 具有了分布式爬取的功能。 2 分布式爬蟲(chóng)技術(shù)方案 Scrapy-redis 分布式爬蟲(chóng)的基本設計理念為主從模式,由作為主控端負責所有網(wǎng)絡(luò )子爬蟲(chóng) 的管理,子爬蟲(chóng)只須要從主控端那兒接收任務(wù)分布式爬蟲(chóng)框架,并把新生成任務(wù)遞交給主控端,在整個(gè)爬取的 過(guò)程中毋須與其他爬蟲(chóng)通訊。 主要有幾個(gè)技術(shù)關(guān)鍵點(diǎn): 2.1 子爬蟲(chóng)爬取任務(wù)的分發(fā) 通過(guò)在主控端安裝一個(gè) redis 數據庫,維護統一的任務(wù)列表,子爬蟲(chóng)每次聯(lián)接 redis 庫調用 lpop()方法,生成一個(gè)任務(wù),并生成一個(gè) request,接下去就是就像通常爬蟲(chóng)工作。
2.2 用戶(hù)登入 由于網(wǎng)站對于旅客的訪(fǎng)問(wèn)有限制,為了爬取所需信息,必須在程序中實(shí)現用戶(hù)登陸,其原 理就是能獲取到有效的本地 cookie,并借助該 cookie 進(jìn)行網(wǎng)站訪(fǎng)問(wèn),除了通常還能用第三方庫 進(jìn)行圖象辨識的驗證方法外,一般采用瀏覽器中自動(dòng)登入,通過(guò)網(wǎng)路工具截取有效的 cookie, 然后在爬蟲(chóng)生成 request 時(shí)附送上 cookie。 2.3 url 的去重 龍源期刊網(wǎng) scrapy_redis 有一個(gè) dupefilter 文件中包含 RFPDupeFilter 類(lèi)用于過(guò)濾新增的 url,可以在該 類(lèi) request_seen 中借助 redis 的 key 的查找功能,如果所爬取的任務(wù)數以?xún)|計則建議 Bloomfilter 去重的方法對于 URL 的儲存和操作方法進(jìn)行優(yōu)化,雖然該方法會(huì )導致大于萬(wàn)分之一的過(guò)濾遺 失率。 2.4 數據寫(xiě)入 選擇非關(guān)系性數據庫 MongoDB 作為硬碟數據庫與 scrapy 進(jìn)行搭配使用,在 pipeline 中對 item 數據進(jìn)行 MongoDB 的寫(xiě)入操作。 3 基本實(shí)現步驟 配置:Windows7 64-bit、Python:2.7.11、 Anaconda 4.0.0 (64-bit)、IDE:Pycharm 3.4.1、Scrapy:1.3.2Redis:X64-3.2、MongoDB:3.2.12 代碼實(shí)現須要對幾個(gè)文件進(jìn)行設置和編撰:items、settings、spiders、pipelines。
Items:這是一個(gè)爬取數據的基礎數據結構類(lèi),由其來(lái)儲存爬蟲(chóng)爬取的鍵值性數據,關(guān)鍵 的就是這條句子:_id = Field() _id 表示的生成一個(gè)數據對象,在 Items 中可以按照須要設定 多個(gè)數據對象。 Settings:ITEM_PIPELINES 該參數決定了 item 的處理方式;DOWNLOAD_DELAY 這個(gè) 是下載的間隔時(shí)間;SCHEDULER 指定作為總的任務(wù)協(xié)調器的類(lèi); SCHEDULER_QUEUE_CLASS 這個(gè)參數是設定處理 URL 的隊列的工作模式一共有四種,一般 選用 SpiderSimpleQueue 即可。 spiders:該文件就是爬蟲(chóng)主要功能的實(shí)現,首先設定該爬蟲(chóng)的基本信息:name、domain、 redis_key、start_urls。爬蟲(chóng)的第一步都是執行方式 start_requests,其中核心句子 yield Request (url,callback)用以按照 url 產(chǎn)生一個(gè) request 并且將 response 結果回傳給 callback 方法。 callback 的方式中通常借助 xpath 或者正則表達式對 response 中包含的 html 代碼進(jìn)行解析,產(chǎn) 生所須要的數據以及新的任務(wù) url。
pipelines:該文件作為數據處理、存儲的代碼段分布式爬蟲(chóng)框架,將在 items 數據被創(chuàng )建后被調用,其中 process_item 的方式就是被調用的方式,所以一定要將其重畫(huà),根據實(shí)際須要把數據借助方式 dict()轉化為字典數據,最后寫(xiě)入 MongoDB。 完成編撰后,在布署的時(shí)侯,start_url 的隊列只能是第一個(gè)運行的爬蟲(chóng)進(jìn)行初始化,后續 運行的爬蟲(chóng)只能是把新的 url 進(jìn)行寫(xiě)入不能對其進(jìn)行再度初始化,部署爬蟲(chóng)的步驟也很簡(jiǎn)單, 只須要把相關(guān)的代碼拷貝到目標筆記本上,讓后 cmd 命令步入 spiders 的文件夾,運行命令 scrapy crawl XXXX,其中 XXXX 就是爬蟲(chóng)的名子,就完成了爬蟲(chóng)的布署和運行了。 龍源期刊網(wǎng) 4 結語(yǔ) 爬蟲(chóng)的實(shí)現,除了基本的步驟和參數設置之外,需要開(kāi)發(fā)者按照實(shí)際網(wǎng)站以及數據情況, 針對性的對爬取的策略、數據的去重、數據篩選進(jìn)行處理,對于爬蟲(chóng)的性能進(jìn)行有效優(yōu)化,為 之后的數據剖析做好良好的數據打算。同時(shí),根據須要可以考慮時(shí)間的誘因加入到數據結構 中,這就要求爬蟲(chóng)還能通過(guò)數據的時(shí)間去進(jìn)行增量爬取。 參考文獻 [1]使用 redis 如何實(shí)現一個(gè)網(wǎng)絡(luò )分布式爬蟲(chóng)[OL].http: //www.oschina.net/code/snippet_209440_20495/. [2]scrapy_redis 的使用解讀[OL].http://www.cnblogs.com/kylinlin/p/5198233.html.http: //blog.csdn.net/u012150179/art
利用 scrapy 集成社區爬蟲(chóng)功能
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 320 次瀏覽 ? 2020-05-13 08:00
當前只爬取了用戶(hù)主頁(yè)上一些簡(jiǎn)單的信息,如果有需求請講到我們的
?。?br />
代碼放到了github上,源碼
如圖所示,在之前的構架上(),我降低了黑色實(shí)線(xiàn)框內的部份,包括:
scrapy是一個(gè)python爬蟲(chóng)框架,想要快速實(shí)現爬蟲(chóng)推薦使用這個(gè)。
可以參考如下資料自行學(xué)習:
官方文檔和官方事例
一個(gè)簡(jiǎn)單明了的入門(mén)博客,注意:博客中scrapy的安裝步驟可以簡(jiǎn)化,直接使用 pip install scrapy,安裝過(guò)程中可能會(huì )缺乏幾個(gè)lib,ubuntu使用 apt-get install libffi-dev libxml2-dev libxslt1-dev -y
mongo特別適宜儲存爬蟲(chóng)數據,支持異構數據。這意味著(zhù)你可以隨時(shí)改變爬蟲(chóng)策略抓取不同的數據,而不用害怕會(huì )和先前的數據沖突(使用sql就須要操蛋的更改表結構了)。
通過(guò)scrapy的pipline來(lái)集成mongo,非常便捷。
安裝mongo
apt-get install mongodb
pip install pymongo
在編撰爬蟲(chóng)的過(guò)程中須要使用xpath表達式來(lái)提取頁(yè)面數據,在chrome中可以使用XPath Helper來(lái)定位元素,非常便捷。使用方式:
打開(kāi)XPath Helper插件
鼠標點(diǎn)擊一下頁(yè)面,按住shift鍵,把鍵盤(pán)聯(lián)通到須要選定的元素上,插件會(huì )將該元素標記為紅色,并給出對應的xpath表達式,如下圖:
在爬蟲(chóng)程序中使用這個(gè)表達式selector.xpath(..../text()").extract()
編寫(xiě)好爬蟲(chóng)后,我門(mén)可以通過(guò)執行scrapy crawl spidername命令來(lái)運行爬蟲(chóng)程序,但這還不夠。
通常我們通過(guò)自動(dòng)或則定時(shí)任務(wù)(cron)來(lái)執行爬蟲(chóng)爬蟲(chóng)社區,而這兒我們須要通過(guò)web應用來(lái)觸發(fā)爬蟲(chóng)。即,當用戶(hù)更新綁定的社交帳號時(shí),去執行一次爬蟲(chóng)。來(lái)剖析一下:
爬蟲(chóng)執行過(guò)程中會(huì )阻塞當前進(jìn)程,為了不阻塞用戶(hù)懇求,必須通過(guò)異步的方法來(lái)運行爬蟲(chóng)。
可能有多個(gè)用戶(hù)同時(shí)更新資料,這就要求才能同時(shí)執行多個(gè)爬蟲(chóng),并且要保證系統不會(huì )超員。
可以擴充成分布式的爬蟲(chóng)。
鑒于項目當前的構架,準備使用celery來(lái)執行異步爬蟲(chóng)。但是遇到了兩個(gè)問(wèn)題:
scrapy框架下,需要在scrapy目錄下執行爬蟲(chóng),否則難以獲取到settings,這個(gè)用上去有點(diǎn)別扭,不過(guò)能夠解決。
celery中反復運行scrapy的爬蟲(chóng)會(huì )報錯:raise error.ReactorNotRestartable()。原因是scrapy用的twisted調度框架,不可以在進(jìn)程中重啟。
stackoverflow上有討論過(guò)這個(gè)問(wèn)題,嘗試了一下,搞不定,放棄這個(gè)方案。如果你有解決這個(gè)問(wèn)題的方式,期待分享:)
scrapy文檔中提及了可以使用scrapyd來(lái)布署,scrapyd是一個(gè)用于運行scrapy爬蟲(chóng)的webservice,使用者才能通過(guò)http請求來(lái)運行爬蟲(chóng)。
你只須要使用scrapyd-client將爬蟲(chóng)發(fā)布到scrapyd中,然后通過(guò)如下命令就可以運行爬蟲(chóng)程序。
$ curl http://localhost:6800/schedule.json -d project=myproject -d spider=spider2
{"status": "ok", "jobid": "26d1b1a6d6f111e0be5c001e648c57f8"}
這意味哪些:
爬蟲(chóng)應用和自己的web應用完全前饋,只有一個(gè)http插口。
由于使用http插口,爬蟲(chóng)可以放到任何還能被訪(fǎng)問(wèn)的主機上運行。一個(gè)簡(jiǎn)易的分布式爬蟲(chóng),不是嗎?
scrapyd使用sqlite隊列來(lái)保存爬蟲(chóng)任務(wù),實(shí)現異步執行。
scrapyd可以同時(shí)執行多個(gè)爬蟲(chóng),最大進(jìn)程數可配,防止系統過(guò)載。
歡迎使用我們的爬蟲(chóng)功能來(lái)搜集社交資料。
成為雨點(diǎn)兒網(wǎng)用戶(hù)爬蟲(chóng)社區,進(jìn)入用戶(hù)主頁(yè),點(diǎn)擊編輯按鍵
填寫(xiě)社交帳號,點(diǎn)擊更新按鍵
爬蟲(chóng)會(huì )在幾秒內完成工作,刷新個(gè)人主頁(yè)能夠看見(jiàn)你的社區資料了,你也可以把個(gè)人主頁(yè)鏈接附在電子簡(jiǎn)歷中喲:) 查看全部
社區活躍度或則貢獻越來(lái)越遭到注重,往往會(huì )作為獲得工作或則承接項目的加分項。為了便捷用戶(hù)展示自己的社區資料,中降低了一個(gè)社區爬蟲(chóng)功能。
當前只爬取了用戶(hù)主頁(yè)上一些簡(jiǎn)單的信息,如果有需求請講到我們的
?。?br />

代碼放到了github上,源碼
如圖所示,在之前的構架上(),我降低了黑色實(shí)線(xiàn)框內的部份,包括:

scrapy是一個(gè)python爬蟲(chóng)框架,想要快速實(shí)現爬蟲(chóng)推薦使用這個(gè)。
可以參考如下資料自行學(xué)習:
官方文檔和官方事例
一個(gè)簡(jiǎn)單明了的入門(mén)博客,注意:博客中scrapy的安裝步驟可以簡(jiǎn)化,直接使用 pip install scrapy,安裝過(guò)程中可能會(huì )缺乏幾個(gè)lib,ubuntu使用 apt-get install libffi-dev libxml2-dev libxslt1-dev -y
mongo特別適宜儲存爬蟲(chóng)數據,支持異構數據。這意味著(zhù)你可以隨時(shí)改變爬蟲(chóng)策略抓取不同的數據,而不用害怕會(huì )和先前的數據沖突(使用sql就須要操蛋的更改表結構了)。
通過(guò)scrapy的pipline來(lái)集成mongo,非常便捷。
安裝mongo
apt-get install mongodb
pip install pymongo
在編撰爬蟲(chóng)的過(guò)程中須要使用xpath表達式來(lái)提取頁(yè)面數據,在chrome中可以使用XPath Helper來(lái)定位元素,非常便捷。使用方式:
打開(kāi)XPath Helper插件
鼠標點(diǎn)擊一下頁(yè)面,按住shift鍵,把鍵盤(pán)聯(lián)通到須要選定的元素上,插件會(huì )將該元素標記為紅色,并給出對應的xpath表達式,如下圖:

在爬蟲(chóng)程序中使用這個(gè)表達式selector.xpath(..../text()").extract()
編寫(xiě)好爬蟲(chóng)后,我門(mén)可以通過(guò)執行scrapy crawl spidername命令來(lái)運行爬蟲(chóng)程序,但這還不夠。
通常我們通過(guò)自動(dòng)或則定時(shí)任務(wù)(cron)來(lái)執行爬蟲(chóng)爬蟲(chóng)社區,而這兒我們須要通過(guò)web應用來(lái)觸發(fā)爬蟲(chóng)。即,當用戶(hù)更新綁定的社交帳號時(shí),去執行一次爬蟲(chóng)。來(lái)剖析一下:
爬蟲(chóng)執行過(guò)程中會(huì )阻塞當前進(jìn)程,為了不阻塞用戶(hù)懇求,必須通過(guò)異步的方法來(lái)運行爬蟲(chóng)。
可能有多個(gè)用戶(hù)同時(shí)更新資料,這就要求才能同時(shí)執行多個(gè)爬蟲(chóng),并且要保證系統不會(huì )超員。
可以擴充成分布式的爬蟲(chóng)。
鑒于項目當前的構架,準備使用celery來(lái)執行異步爬蟲(chóng)。但是遇到了兩個(gè)問(wèn)題:
scrapy框架下,需要在scrapy目錄下執行爬蟲(chóng),否則難以獲取到settings,這個(gè)用上去有點(diǎn)別扭,不過(guò)能夠解決。
celery中反復運行scrapy的爬蟲(chóng)會(huì )報錯:raise error.ReactorNotRestartable()。原因是scrapy用的twisted調度框架,不可以在進(jìn)程中重啟。
stackoverflow上有討論過(guò)這個(gè)問(wèn)題,嘗試了一下,搞不定,放棄這個(gè)方案。如果你有解決這個(gè)問(wèn)題的方式,期待分享:)
scrapy文檔中提及了可以使用scrapyd來(lái)布署,scrapyd是一個(gè)用于運行scrapy爬蟲(chóng)的webservice,使用者才能通過(guò)http請求來(lái)運行爬蟲(chóng)。
你只須要使用scrapyd-client將爬蟲(chóng)發(fā)布到scrapyd中,然后通過(guò)如下命令就可以運行爬蟲(chóng)程序。
$ curl http://localhost:6800/schedule.json -d project=myproject -d spider=spider2
{"status": "ok", "jobid": "26d1b1a6d6f111e0be5c001e648c57f8"}
這意味哪些:
爬蟲(chóng)應用和自己的web應用完全前饋,只有一個(gè)http插口。
由于使用http插口,爬蟲(chóng)可以放到任何還能被訪(fǎng)問(wèn)的主機上運行。一個(gè)簡(jiǎn)易的分布式爬蟲(chóng),不是嗎?
scrapyd使用sqlite隊列來(lái)保存爬蟲(chóng)任務(wù),實(shí)現異步執行。
scrapyd可以同時(shí)執行多個(gè)爬蟲(chóng),最大進(jìn)程數可配,防止系統過(guò)載。
歡迎使用我們的爬蟲(chóng)功能來(lái)搜集社交資料。
成為雨點(diǎn)兒網(wǎng)用戶(hù)爬蟲(chóng)社區,進(jìn)入用戶(hù)主頁(yè),點(diǎn)擊編輯按鍵

填寫(xiě)社交帳號,點(diǎn)擊更新按鍵

爬蟲(chóng)會(huì )在幾秒內完成工作,刷新個(gè)人主頁(yè)能夠看見(jiàn)你的社區資料了,你也可以把個(gè)人主頁(yè)鏈接附在電子簡(jiǎn)歷中喲:)
[讀后筆記](méi) python網(wǎng)路爬蟲(chóng)實(shí)戰 (李松濤)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 343 次瀏覽 ? 2020-05-12 08:03
用了大約一個(gè)晚上的時(shí)間,就把這本書(shū)看完了。
前面4章是基礎的python知識,有基礎的朋友可以略過(guò)。
scrapy爬蟲(chóng)部份,用了實(shí)例給你們說(shuō)明scrapy的用法網(wǎng)絡(luò )爬蟲(chóng)實(shí)例,不過(guò)若果之前沒(méi)用過(guò)scrapy的話(huà),需要漸漸上機敲擊代碼。
其實(shí)書(shū)中的事例都是很簡(jiǎn)單的事例,基本沒(méi)哪些反爬的限制,書(shū)中一句話(huà)說(shuō)的十分贊成,用scrapy寫(xiě)爬蟲(chóng),就是做填空題,而用urllib2寫(xiě)爬蟲(chóng),就是習作題,可以自由發(fā)揮。
書(shū)中沒(méi)有用更為便捷的requests庫。 內容搜索用的最多的是beatifulsoup, 對于xpah或則lxml介紹的比較少。 因為scrapy自帶的response就是可以直接用xpath,更為便捷。
對于scrapy的中間和pipeline的使用了一個(gè)事例,也是比較簡(jiǎn)單的反例。
書(shū)中沒(méi)有對驗證碼,分布式等流行的反爬進(jìn)行講解,應該適宜爬蟲(chóng)入門(mén)的朋友去看吧。
書(shū)中一點(diǎn)挺好的就是代碼都十分規范,而且雖然是寫(xiě)習作的使用urllib2,也有意模仿scrapy的框架去寫(xiě), 需要抓取的數據 獨立一個(gè)類(lèi),類(lèi)似于scrapy的item,數據處理用的也是叫pipleline的方式。
這樣寫(xiě)的益處就是, 每個(gè)模塊的功能都一目了然,看完第一個(gè)反例的類(lèi)和函數定義,后面的事例都是大同小異,可以推動(dòng)讀者的閱讀速率,非常贊。(這一點(diǎn)之后自己要學(xué)習,增加代碼的可復用性)
很多頁(yè)面url如今早已過(guò)期了,再次運行作者的源碼會(huì )返回好多404的結果。
失效的項目:
金逸影城
天氣預報
獲取代理:
本書(shū)的一些錯誤的地方:
1. 獲取金逸影廳的spider中,所有關(guān)于movie的拼寫(xiě)都拼錯為moive了。這個(gè)屬于德語(yǔ)錯誤。
2. 在testProxy.py 代碼中網(wǎng)絡(luò )爬蟲(chóng)實(shí)例, 由于在同一個(gè)類(lèi)中,一直在形成線(xiàn)程,最后造成線(xiàn)程過(guò)多,不能再形成線(xiàn)程。程序會(huì )中途退出。
File "C:\Python27\lib\threading.py", line 736, in start<br />
_start_new_thread(self.__bootstrap, ())<br />
thread.error: can't start new thread
可以更改成獨立函數的方式,而不是類(lèi)函數。
待續。 查看全部

用了大約一個(gè)晚上的時(shí)間,就把這本書(shū)看完了。
前面4章是基礎的python知識,有基礎的朋友可以略過(guò)。
scrapy爬蟲(chóng)部份,用了實(shí)例給你們說(shuō)明scrapy的用法網(wǎng)絡(luò )爬蟲(chóng)實(shí)例,不過(guò)若果之前沒(méi)用過(guò)scrapy的話(huà),需要漸漸上機敲擊代碼。
其實(shí)書(shū)中的事例都是很簡(jiǎn)單的事例,基本沒(méi)哪些反爬的限制,書(shū)中一句話(huà)說(shuō)的十分贊成,用scrapy寫(xiě)爬蟲(chóng),就是做填空題,而用urllib2寫(xiě)爬蟲(chóng),就是習作題,可以自由發(fā)揮。
書(shū)中沒(méi)有用更為便捷的requests庫。 內容搜索用的最多的是beatifulsoup, 對于xpah或則lxml介紹的比較少。 因為scrapy自帶的response就是可以直接用xpath,更為便捷。
對于scrapy的中間和pipeline的使用了一個(gè)事例,也是比較簡(jiǎn)單的反例。
書(shū)中沒(méi)有對驗證碼,分布式等流行的反爬進(jìn)行講解,應該適宜爬蟲(chóng)入門(mén)的朋友去看吧。
書(shū)中一點(diǎn)挺好的就是代碼都十分規范,而且雖然是寫(xiě)習作的使用urllib2,也有意模仿scrapy的框架去寫(xiě), 需要抓取的數據 獨立一個(gè)類(lèi),類(lèi)似于scrapy的item,數據處理用的也是叫pipleline的方式。
這樣寫(xiě)的益處就是, 每個(gè)模塊的功能都一目了然,看完第一個(gè)反例的類(lèi)和函數定義,后面的事例都是大同小異,可以推動(dòng)讀者的閱讀速率,非常贊。(這一點(diǎn)之后自己要學(xué)習,增加代碼的可復用性)
很多頁(yè)面url如今早已過(guò)期了,再次運行作者的源碼會(huì )返回好多404的結果。
失效的項目:
金逸影城
天氣預報
獲取代理:
本書(shū)的一些錯誤的地方:
1. 獲取金逸影廳的spider中,所有關(guān)于movie的拼寫(xiě)都拼錯為moive了。這個(gè)屬于德語(yǔ)錯誤。
2. 在testProxy.py 代碼中網(wǎng)絡(luò )爬蟲(chóng)實(shí)例, 由于在同一個(gè)類(lèi)中,一直在形成線(xiàn)程,最后造成線(xiàn)程過(guò)多,不能再形成線(xiàn)程。程序會(huì )中途退出。
File "C:\Python27\lib\threading.py", line 736, in start<br />
_start_new_thread(self.__bootstrap, ())<br />
thread.error: can't start new thread
可以更改成獨立函數的方式,而不是類(lèi)函數。
待續。
【Scrapy】走進(jìn)成熟的爬蟲(chóng)框架
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 338 次瀏覽 ? 2020-05-10 08:02
今天簡(jiǎn)單說(shuō)說(shuō)Scrapy的安裝。
前幾天有小伙伴留言說(shuō)能不能介紹推薦一下爬蟲(chóng)框架,我給他推薦了Scrapy,本來(lái)想偷個(gè)懶,推薦他去看官方文檔,里面有一些demo代碼可供學(xué)習測試。結果收到回復說(shuō)文檔中演示用到的網(wǎng)站已經(jīng)難以訪(fǎng)問(wèn)了。所以只能自己來(lái)簡(jiǎn)單寫(xiě)一下了,也算是自己一個(gè)學(xué)習記錄。
Scrapy是哪些?
定義介紹我也不復制粘貼了。簡(jiǎn)單來(lái)說(shuō),Scrapy是一個(gè)中小型的爬蟲(chóng)框架,框架的意義就在于幫你預設好了好多可以用的東西,讓你可以從復雜的數據流和底層控制中抽離下來(lái),專(zhuān)心于頁(yè)面的解析即可完成中大項目爬蟲(chóng),甚至是分布式爬蟲(chóng)。
但是爬蟲(chóng)入門(mén)是不推薦直接從框架入手的,直接從框架入手會(huì )使你頭暈目眩,覺(jué)得哪里哪里都看不懂,有點(diǎn)類(lèi)似于還沒(méi)學(xué)會(huì )基礎的措詞造句就直接套用模板寫(xiě)成文章,自然是非常費力的。所以還是推薦你們有一定的手寫(xiě)爬蟲(chóng)基礎再深入了解框架。(當然還沒(méi)有入門(mén)爬蟲(chóng)的朋友…可以催更我的爬蟲(chóng)入門(mén)文章…)
那么首先是安裝。
Python的版本選擇之前提過(guò),推薦你們全面擁抱Python 3.x。
很久以前,大概是我剛入門(mén)學(xué)習Scrapy時(shí)爬蟲(chóng)框架,Scrapy還沒(méi)有支持Python 3.x,那時(shí)一部分爬蟲(chóng)工程師把Scrapy不支持Python 3.x作為不進(jìn)行遷移的理由。當然了,那時(shí)更具體的緣由是Scrapy所依賴(lài)的twisted和mitmproxy不支持Python 3.x。
現在我仍然推薦你們全面擁抱Python 3.x。
先安裝Python
這次我們以本地環(huán)境來(lái)進(jìn)行安裝(Windows+Anaconda),由于Python的跨平臺特點(diǎn)爬蟲(chóng)框架,我們本地寫(xiě)的代碼可以很容易遷移到別的筆記本或服務(wù)器使用。(當然了,從規范使用的角度上推薦你們使用單獨的env,或者直接使用docker或則vagrant,不過(guò)那就說(shuō)來(lái)話(huà)長(cháng)了…以后可以考慮單獨介紹)
按照慣例,我們直接使用 pip install scrapy 進(jìn)行安裝。
那么,你大幾率會(huì )碰到這樣的錯誤:
具體的錯誤緣由…缺少Microsoft Visual C++ 14.0…你也可以自己通過(guò)其他渠道解決,當然我們最推薦的做法是直接使用 conda install scrapy 命令(前提是你安裝了Anaconda而非普通Python)。
如果碰到寫(xiě)入權限錯誤,請用管理員模式運行cmd。
之后我們可以寫(xiě)一個(gè)太小的demo,依然是官方案例中的DMOZ,DMOZ網(wǎng)站是一個(gè)知名的開(kāi)放式分類(lèi)目錄(Open DirectoryProject),原版的DMOZ已于今年的3月17日停止了營(yíng)運,目前網(wǎng)站處于403狀態(tài)。但是網(wǎng)上大量過(guò)去的教程都是以DMOZ為案例的。我為你們找到了原DMOZ網(wǎng)站的靜態(tài)鏡像站,大家可以直接訪(fǎng)問(wèn)
大家根據官方文檔的步驟繼續做就可以了,后續的問(wèn)題不大。
?。ǎ?br /> 需要注意的就是工作目錄問(wèn)題。
啟動(dòng)Scrapy項目。
scrapy startproject tutorial
進(jìn)入目錄,我們可以看見(jiàn)手動(dòng)生成的一些文件,這些文件就是scrapy框架所須要的最基礎的組織結構。
scrapy.cfg: 項目的配置文件
tutorial/: 該項目的python模塊。之后您將在此加入代碼。
tutorial/items.py: 項目中的item文件.
tutorial/pipelines.py: 項目中的pipelines文件.
tutorial/settings.py: 項目的設置文件.
tutorial/spiders/: 放置spider代碼的目錄. 查看全部

今天簡(jiǎn)單說(shuō)說(shuō)Scrapy的安裝。
前幾天有小伙伴留言說(shuō)能不能介紹推薦一下爬蟲(chóng)框架,我給他推薦了Scrapy,本來(lái)想偷個(gè)懶,推薦他去看官方文檔,里面有一些demo代碼可供學(xué)習測試。結果收到回復說(shuō)文檔中演示用到的網(wǎng)站已經(jīng)難以訪(fǎng)問(wèn)了。所以只能自己來(lái)簡(jiǎn)單寫(xiě)一下了,也算是自己一個(gè)學(xué)習記錄。
Scrapy是哪些?
定義介紹我也不復制粘貼了。簡(jiǎn)單來(lái)說(shuō),Scrapy是一個(gè)中小型的爬蟲(chóng)框架,框架的意義就在于幫你預設好了好多可以用的東西,讓你可以從復雜的數據流和底層控制中抽離下來(lái),專(zhuān)心于頁(yè)面的解析即可完成中大項目爬蟲(chóng),甚至是分布式爬蟲(chóng)。
但是爬蟲(chóng)入門(mén)是不推薦直接從框架入手的,直接從框架入手會(huì )使你頭暈目眩,覺(jué)得哪里哪里都看不懂,有點(diǎn)類(lèi)似于還沒(méi)學(xué)會(huì )基礎的措詞造句就直接套用模板寫(xiě)成文章,自然是非常費力的。所以還是推薦你們有一定的手寫(xiě)爬蟲(chóng)基礎再深入了解框架。(當然還沒(méi)有入門(mén)爬蟲(chóng)的朋友…可以催更我的爬蟲(chóng)入門(mén)文章…)
那么首先是安裝。
Python的版本選擇之前提過(guò),推薦你們全面擁抱Python 3.x。
很久以前,大概是我剛入門(mén)學(xué)習Scrapy時(shí)爬蟲(chóng)框架,Scrapy還沒(méi)有支持Python 3.x,那時(shí)一部分爬蟲(chóng)工程師把Scrapy不支持Python 3.x作為不進(jìn)行遷移的理由。當然了,那時(shí)更具體的緣由是Scrapy所依賴(lài)的twisted和mitmproxy不支持Python 3.x。
現在我仍然推薦你們全面擁抱Python 3.x。
先安裝Python
這次我們以本地環(huán)境來(lái)進(jìn)行安裝(Windows+Anaconda),由于Python的跨平臺特點(diǎn)爬蟲(chóng)框架,我們本地寫(xiě)的代碼可以很容易遷移到別的筆記本或服務(wù)器使用。(當然了,從規范使用的角度上推薦你們使用單獨的env,或者直接使用docker或則vagrant,不過(guò)那就說(shuō)來(lái)話(huà)長(cháng)了…以后可以考慮單獨介紹)
按照慣例,我們直接使用 pip install scrapy 進(jìn)行安裝。
那么,你大幾率會(huì )碰到這樣的錯誤:

具體的錯誤緣由…缺少Microsoft Visual C++ 14.0…你也可以自己通過(guò)其他渠道解決,當然我們最推薦的做法是直接使用 conda install scrapy 命令(前提是你安裝了Anaconda而非普通Python)。
如果碰到寫(xiě)入權限錯誤,請用管理員模式運行cmd。

之后我們可以寫(xiě)一個(gè)太小的demo,依然是官方案例中的DMOZ,DMOZ網(wǎng)站是一個(gè)知名的開(kāi)放式分類(lèi)目錄(Open DirectoryProject),原版的DMOZ已于今年的3月17日停止了營(yíng)運,目前網(wǎng)站處于403狀態(tài)。但是網(wǎng)上大量過(guò)去的教程都是以DMOZ為案例的。我為你們找到了原DMOZ網(wǎng)站的靜態(tài)鏡像站,大家可以直接訪(fǎng)問(wèn)
大家根據官方文檔的步驟繼續做就可以了,后續的問(wèn)題不大。
?。ǎ?br /> 需要注意的就是工作目錄問(wèn)題。
啟動(dòng)Scrapy項目。
scrapy startproject tutorial

進(jìn)入目錄,我們可以看見(jiàn)手動(dòng)生成的一些文件,這些文件就是scrapy框架所須要的最基礎的組織結構。
scrapy.cfg: 項目的配置文件
tutorial/: 該項目的python模塊。之后您將在此加入代碼。
tutorial/items.py: 項目中的item文件.
tutorial/pipelines.py: 項目中的pipelines文件.
tutorial/settings.py: 項目的設置文件.
tutorial/spiders/: 放置spider代碼的目錄.
Scrapy爬蟲(chóng)框架:抓取天貓淘寶數據
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 422 次瀏覽 ? 2020-05-05 08:05
通過(guò)天貓的搜索,獲取搜索下來(lái)的每件商品的銷(xiāo)量、收藏數、價(jià)格。
所以,最終的目的是通過(guò)獲取兩個(gè)頁(yè)面的內容,一個(gè)是搜索結果,從上面找下來(lái)每一個(gè)商品的詳盡地址,然后第二個(gè)是商品詳盡內容,從上面獲取到銷(xiāo)量、價(jià)格等。
有了思路如今我們先下載搜索結果頁(yè)面,然后再下載頁(yè)面中每一項詳盡信息頁(yè)面。
def _parse_handler(self, response):
''' 下載頁(yè)面 """
self.driver.get(response.url)
pass
很簡(jiǎn)單,通過(guò)self.driver.get(response.url)就能使用selenium下載內容,如果直接使用response中的網(wǎng)頁(yè)內容是靜態(tài)的。
上面說(shuō)了怎樣下載內容,當我們下載好內容后,需要從上面去獲取我們想要的有用信息,這里就要用到選擇器,選擇器構造方法比較多,只介紹一種,這里看詳盡信息:
>>> body = '<html><body><span>good</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').extract()
[u'good']
這樣就通過(guò)xpath取下來(lái)了good這個(gè)詞組,更詳盡的xpath教程點(diǎn)擊這兒。
Selector 提供了好多形式出了xpath,還有css選擇器,正則表達式,中文教程看這個(gè),具體內容就不多說(shuō),只須要曉得這樣可以快速獲取我們須要的內容。
簡(jiǎn)單的介紹了如何獲取內容后,現在我們從第一個(gè)搜索結果中獲取我們想要的商品詳盡鏈接,通過(guò)查看網(wǎng)頁(yè)源代碼可以看見(jiàn),商品的鏈接在這里:
...
<p class="title">
<a class="J_ClickStat" data-nid="523242229702" href="//detail.tmall.com/item.htm?spm=a230r.1.14.46.Mnbjq5&id=523242229702&ns=1&abbucket=14" target="_blank" trace="msrp_auction" traceidx="5" trace-pid="" data-spm-anchor-id="a230r.1.14.46">WD/西部數據 WD30EZRZ臺式機3T電腦<span class="H">硬盤(pán)</span> 西數藍盤(pán)3TB 替綠盤(pán)</a>
</p>
...
使用之前的規則來(lái)獲取到a元素的href屬性就是須要的內容:
selector = Selector(text=self.driver.page_source) # 這里不要省略text因為省略后Selector使用的是另外一個(gè)構造函數,self.driver.page_source是這個(gè)網(wǎng)頁(yè)的html內容
selector.css(".title").css(".J_ClickStat").xpath("./@href").extract()
簡(jiǎn)單說(shuō)一下,這里通過(guò)css工具取了class叫title的p元素,然后又獲取了class是J_ClickStat的a元素,最后通過(guò)xpath規則獲取a元素的href中的內容。啰嗦一句css中若果是取id則應當是selector.css("#title"),這個(gè)和css中的選擇器是一致的。
同理,我們獲取到商品詳情后,以獲取銷(xiāo)量為例,查看源代碼:
<ul class="tm-ind-panel">
<li class="tm-ind-item tm-ind-sellCount" data-label="月銷(xiāo)量"><div class="tm-indcon"><span class="tm-label">月銷(xiāo)量</span><span class="tm-count">881</span></div></li>
<li class="tm-ind-item tm-ind-reviewCount canClick tm-line3" id="J_ItemRates"><div class="tm-indcon"><span class="tm-label">累計評價(jià)</span><span class="tm-count">4593</span></div></li>
<li class="tm-ind-item tm-ind-emPointCount" data-spm="1000988"><div class="tm-indcon"><a href="//vip.tmall.com/vip/index.htm" target="_blank"><span class="tm-label">送天貓積分</span><span class="tm-count">55</span></a></div></li>
</ul>
獲取月銷(xiāo)量:
selector.css(".tm-ind-sellCount").xpath("./div/span[@class='tm-count']/text()").extract_first()
獲取累計評價(jià):
selector.css(".tm-ind-reviewCount").xpath("./div[@class='tm-indcon']/span[@class='tm-count']/text()").extract_first()
最后把獲取下來(lái)的數據包裝成Item返回。淘寶或則淘寶她們的頁(yè)面內容不一樣,所以規則也不同,需要分開(kāi)去獲取想要的內容。
Item是scrapy中獲取下來(lái)的結果,后面可以處理這種結果。
Item通常是放在items.py中
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
>>> product = Product(name='Desktop PC', price=1000)
>>> print product
Product(name='Desktop PC', price=1000)
>>> product['name']
Desktop PC
>>> product.get('name')
Desktop PC
>>> product['price']
1000
>>> product['last_updated']
Traceback (most recent call last):
...
KeyError: 'last_updated'
>>> product.get('last_updated', 'not set')
not set
>>> product['lala'] # getting unknown field
Traceback (most recent call last):
...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product # is name field populated?
True
>>> 'last_updated' in product # is last_updated populated?
False
>>> 'last_updated' in product.fields # is last_updated a declared field?
True
>>> 'lala' in product.fields # is lala a declared field?
False
>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
...
KeyError: 'Product does not support field: lala'
這里只須要注意一個(gè)地方,不能通過(guò)product.name的方法獲取,也不能通過(guò)product.name = "name"的形式設置值。
當Item在Spider中被搜集以后,它將會(huì )被傳遞到Item Pipeline,一些組件會(huì )根據一定的次序執行對Item的處理。
每個(gè)item pipeline組件(有時(shí)稱(chēng)之為“Item Pipeline”)是實(shí)現了簡(jiǎn)單方式的Python類(lèi)。他們接收到Item并通過(guò)它執行一些行為,同時(shí)也決定此Item是否繼續通過(guò)pipeline,或是被遺棄而不再進(jìn)行處理。
以下是item pipeline的一些典型應用:
現在實(shí)現一個(gè)Item過(guò)濾器,我們把獲取下來(lái)若果是None的數據形參為0,如果Item對象是None則丟棄這條數據。
pipeline通常是放在pipelines.py中
def process_item(self, item, spider):
if item is not None:
if item["p_standard_price"] is None:
item["p_standard_price"] = item["p_shop_price"]
if item["p_shop_price"] is None:
item["p_shop_price"] = item["p_standard_price"]
item["p_collect_count"] = text_utils.to_int(item["p_collect_count"])
item["p_comment_count"] = text_utils.to_int(item["p_comment_count"])
item["p_month_sale_count"] = text_utils.to_int(item["p_month_sale_count"])
item["p_sale_count"] = text_utils.to_int(item["p_sale_count"])
item["p_standard_price"] = text_utils.to_string(item["p_standard_price"], "0")
item["p_shop_price"] = text_utils.to_string(item["p_shop_price"], "0")
item["p_pay_count"] = item["p_pay_count"] if item["p_pay_count"] is not "-" else "0"
return item
else:
raise DropItem("Item is None %s" % item)
最后須要在settings.py中添加這個(gè)pipeline
ITEM_PIPELINES = {
'TaoBao.pipelines.TTDataHandlerPipeline': 250,
'TaoBao.pipelines.MysqlPipeline': 300,
}
后面那種數字越小,則執行的次序越靠前,這里先過(guò)濾處理數據,獲取到正確的數據后,再執行TaoBao.pipelines.MysqlPipeline添加數據到數據庫。
完整的代碼:[不帶數據庫版本][ 數據庫版本]。
之前說(shuō)的方法都是直接通過(guò)命令scrapy crawl tts來(lái)啟動(dòng)。怎么用IDE的調試功能呢?很簡(jiǎn)單通過(guò)main函數啟動(dòng)爬蟲(chóng):
# 寫(xiě)到Spider里面
if __name__ == "__main__":
settings = get_project_settings()
process = CrawlerProcess(settings)
spider = TmallAndTaoBaoSpider
process.crawl(spider)
process.start()
在獲取數據的時(shí)侯,很多時(shí)侯會(huì )碰到網(wǎng)頁(yè)重定向的問(wèn)題,scrapy會(huì )返回302之后不會(huì )手動(dòng)重定向后繼續爬取新地址,在scrapy的設置中,可以通過(guò)配置來(lái)開(kāi)啟重定向,這樣雖然域名是重定向的scrapy也會(huì )手動(dòng)到最終的地址獲取內容。
解決方案:settings.py中添加REDIRECT_ENABLED = True
很多時(shí)侯爬蟲(chóng)都有自定義數據,比如之前寫(xiě)的是硬碟關(guān)鍵字,現在通過(guò)參數的方法如何傳遞呢?
解決方案:
大部分時(shí)侯,我們可以取到完整的網(wǎng)頁(yè)信息,如果網(wǎng)頁(yè)的ajax懇求太多,網(wǎng)速很慢的時(shí)侯,selenium并不知道什么時(shí)候ajax懇求完成,這個(gè)時(shí)侯假如通過(guò)self.driver.get(response.url)獲取頁(yè)面天貓反爬蟲(chóng),然后通過(guò)Selector取數據天貓反爬蟲(chóng),很可能還沒(méi)加載完成取不到數據。
解決方案:通過(guò)selenium提供的工具來(lái)延后獲取內容,直到獲取到數據,或者超時(shí)。 查看全部
有了前兩篇的基礎,接下來(lái)通過(guò)抓取天貓和淘寶的數據來(lái)詳盡說(shuō)明,如何通過(guò)Scrapy爬取想要的內容。完整的代碼:[不帶數據庫版本][ 數據庫版本]。
通過(guò)天貓的搜索,獲取搜索下來(lái)的每件商品的銷(xiāo)量、收藏數、價(jià)格。
所以,最終的目的是通過(guò)獲取兩個(gè)頁(yè)面的內容,一個(gè)是搜索結果,從上面找下來(lái)每一個(gè)商品的詳盡地址,然后第二個(gè)是商品詳盡內容,從上面獲取到銷(xiāo)量、價(jià)格等。
有了思路如今我們先下載搜索結果頁(yè)面,然后再下載頁(yè)面中每一項詳盡信息頁(yè)面。
def _parse_handler(self, response):
''' 下載頁(yè)面 """
self.driver.get(response.url)
pass
很簡(jiǎn)單,通過(guò)self.driver.get(response.url)就能使用selenium下載內容,如果直接使用response中的網(wǎng)頁(yè)內容是靜態(tài)的。
上面說(shuō)了怎樣下載內容,當我們下載好內容后,需要從上面去獲取我們想要的有用信息,這里就要用到選擇器,選擇器構造方法比較多,只介紹一種,這里看詳盡信息:
>>> body = '<html><body><span>good</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').extract()
[u'good']
這樣就通過(guò)xpath取下來(lái)了good這個(gè)詞組,更詳盡的xpath教程點(diǎn)擊這兒。
Selector 提供了好多形式出了xpath,還有css選擇器,正則表達式,中文教程看這個(gè),具體內容就不多說(shuō),只須要曉得這樣可以快速獲取我們須要的內容。
簡(jiǎn)單的介紹了如何獲取內容后,現在我們從第一個(gè)搜索結果中獲取我們想要的商品詳盡鏈接,通過(guò)查看網(wǎng)頁(yè)源代碼可以看見(jiàn),商品的鏈接在這里:
...
<p class="title">
<a class="J_ClickStat" data-nid="523242229702" href="//detail.tmall.com/item.htm?spm=a230r.1.14.46.Mnbjq5&id=523242229702&ns=1&abbucket=14" target="_blank" trace="msrp_auction" traceidx="5" trace-pid="" data-spm-anchor-id="a230r.1.14.46">WD/西部數據 WD30EZRZ臺式機3T電腦<span class="H">硬盤(pán)</span> 西數藍盤(pán)3TB 替綠盤(pán)</a>
</p>
...
使用之前的規則來(lái)獲取到a元素的href屬性就是須要的內容:
selector = Selector(text=self.driver.page_source) # 這里不要省略text因為省略后Selector使用的是另外一個(gè)構造函數,self.driver.page_source是這個(gè)網(wǎng)頁(yè)的html內容
selector.css(".title").css(".J_ClickStat").xpath("./@href").extract()
簡(jiǎn)單說(shuō)一下,這里通過(guò)css工具取了class叫title的p元素,然后又獲取了class是J_ClickStat的a元素,最后通過(guò)xpath規則獲取a元素的href中的內容。啰嗦一句css中若果是取id則應當是selector.css("#title"),這個(gè)和css中的選擇器是一致的。
同理,我們獲取到商品詳情后,以獲取銷(xiāo)量為例,查看源代碼:
<ul class="tm-ind-panel">
<li class="tm-ind-item tm-ind-sellCount" data-label="月銷(xiāo)量"><div class="tm-indcon"><span class="tm-label">月銷(xiāo)量</span><span class="tm-count">881</span></div></li>
<li class="tm-ind-item tm-ind-reviewCount canClick tm-line3" id="J_ItemRates"><div class="tm-indcon"><span class="tm-label">累計評價(jià)</span><span class="tm-count">4593</span></div></li>
<li class="tm-ind-item tm-ind-emPointCount" data-spm="1000988"><div class="tm-indcon"><a href="//vip.tmall.com/vip/index.htm" target="_blank"><span class="tm-label">送天貓積分</span><span class="tm-count">55</span></a></div></li>
</ul>
獲取月銷(xiāo)量:
selector.css(".tm-ind-sellCount").xpath("./div/span[@class='tm-count']/text()").extract_first()
獲取累計評價(jià):
selector.css(".tm-ind-reviewCount").xpath("./div[@class='tm-indcon']/span[@class='tm-count']/text()").extract_first()
最后把獲取下來(lái)的數據包裝成Item返回。淘寶或則淘寶她們的頁(yè)面內容不一樣,所以規則也不同,需要分開(kāi)去獲取想要的內容。
Item是scrapy中獲取下來(lái)的結果,后面可以處理這種結果。
Item通常是放在items.py中
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
>>> product = Product(name='Desktop PC', price=1000)
>>> print product
Product(name='Desktop PC', price=1000)
>>> product['name']
Desktop PC
>>> product.get('name')
Desktop PC
>>> product['price']
1000
>>> product['last_updated']
Traceback (most recent call last):
...
KeyError: 'last_updated'
>>> product.get('last_updated', 'not set')
not set
>>> product['lala'] # getting unknown field
Traceback (most recent call last):
...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product # is name field populated?
True
>>> 'last_updated' in product # is last_updated populated?
False
>>> 'last_updated' in product.fields # is last_updated a declared field?
True
>>> 'lala' in product.fields # is lala a declared field?
False
>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
...
KeyError: 'Product does not support field: lala'
這里只須要注意一個(gè)地方,不能通過(guò)product.name的方法獲取,也不能通過(guò)product.name = "name"的形式設置值。
當Item在Spider中被搜集以后,它將會(huì )被傳遞到Item Pipeline,一些組件會(huì )根據一定的次序執行對Item的處理。
每個(gè)item pipeline組件(有時(shí)稱(chēng)之為“Item Pipeline”)是實(shí)現了簡(jiǎn)單方式的Python類(lèi)。他們接收到Item并通過(guò)它執行一些行為,同時(shí)也決定此Item是否繼續通過(guò)pipeline,或是被遺棄而不再進(jìn)行處理。
以下是item pipeline的一些典型應用:
現在實(shí)現一個(gè)Item過(guò)濾器,我們把獲取下來(lái)若果是None的數據形參為0,如果Item對象是None則丟棄這條數據。
pipeline通常是放在pipelines.py中
def process_item(self, item, spider):
if item is not None:
if item["p_standard_price"] is None:
item["p_standard_price"] = item["p_shop_price"]
if item["p_shop_price"] is None:
item["p_shop_price"] = item["p_standard_price"]
item["p_collect_count"] = text_utils.to_int(item["p_collect_count"])
item["p_comment_count"] = text_utils.to_int(item["p_comment_count"])
item["p_month_sale_count"] = text_utils.to_int(item["p_month_sale_count"])
item["p_sale_count"] = text_utils.to_int(item["p_sale_count"])
item["p_standard_price"] = text_utils.to_string(item["p_standard_price"], "0")
item["p_shop_price"] = text_utils.to_string(item["p_shop_price"], "0")
item["p_pay_count"] = item["p_pay_count"] if item["p_pay_count"] is not "-" else "0"
return item
else:
raise DropItem("Item is None %s" % item)
最后須要在settings.py中添加這個(gè)pipeline
ITEM_PIPELINES = {
'TaoBao.pipelines.TTDataHandlerPipeline': 250,
'TaoBao.pipelines.MysqlPipeline': 300,
}
后面那種數字越小,則執行的次序越靠前,這里先過(guò)濾處理數據,獲取到正確的數據后,再執行TaoBao.pipelines.MysqlPipeline添加數據到數據庫。
完整的代碼:[不帶數據庫版本][ 數據庫版本]。
之前說(shuō)的方法都是直接通過(guò)命令scrapy crawl tts來(lái)啟動(dòng)。怎么用IDE的調試功能呢?很簡(jiǎn)單通過(guò)main函數啟動(dòng)爬蟲(chóng):
# 寫(xiě)到Spider里面
if __name__ == "__main__":
settings = get_project_settings()
process = CrawlerProcess(settings)
spider = TmallAndTaoBaoSpider
process.crawl(spider)
process.start()
在獲取數據的時(shí)侯,很多時(shí)侯會(huì )碰到網(wǎng)頁(yè)重定向的問(wèn)題,scrapy會(huì )返回302之后不會(huì )手動(dòng)重定向后繼續爬取新地址,在scrapy的設置中,可以通過(guò)配置來(lái)開(kāi)啟重定向,這樣雖然域名是重定向的scrapy也會(huì )手動(dòng)到最終的地址獲取內容。
解決方案:settings.py中添加REDIRECT_ENABLED = True
很多時(shí)侯爬蟲(chóng)都有自定義數據,比如之前寫(xiě)的是硬碟關(guān)鍵字,現在通過(guò)參數的方法如何傳遞呢?
解決方案:
大部分時(shí)侯,我們可以取到完整的網(wǎng)頁(yè)信息,如果網(wǎng)頁(yè)的ajax懇求太多,網(wǎng)速很慢的時(shí)侯,selenium并不知道什么時(shí)候ajax懇求完成,這個(gè)時(shí)侯假如通過(guò)self.driver.get(response.url)獲取頁(yè)面天貓反爬蟲(chóng),然后通過(guò)Selector取數據天貓反爬蟲(chóng),很可能還沒(méi)加載完成取不到數據。
解決方案:通過(guò)selenium提供的工具來(lái)延后獲取內容,直到獲取到數據,或者超時(shí)。
網(wǎng)絡(luò )爬蟲(chóng):使用Scrapy框架編撰一個(gè)抓取書(shū)籍信息的爬蟲(chóng)服務(wù)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 285 次瀏覽 ? 2020-05-04 08:06
BeautifulSoup是一個(gè)十分流行的Python網(wǎng)路抓取庫,它提供了一個(gè)基于HTML結構的Python對象。
雖然簡(jiǎn)單易懂,又能非常好的處理HTML數據,
但是相比Scrapy而言網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),BeautifulSoup有一個(gè)最大的缺點(diǎn):慢。
Scrapy 是一個(gè)開(kāi)源的 Python 數據抓取框架,速度快,強大,而且使用簡(jiǎn)單。
來(lái)看一個(gè)官網(wǎng)主頁(yè)上的簡(jiǎn)單并完整的爬蟲(chóng):
雖然只有10行左右的代碼,但是它的確是一個(gè)完整的爬蟲(chóng)服務(wù):
Scrapy所有的懇求都是異步的:
安裝(Mac)
pip install scrapy
其他操作系統請參考完整安裝指導:
Spider類(lèi)想要抒發(fā)的是:如何抓取一個(gè)確定了的網(wǎng)站的數據。比如在start_urls里定義的去那個(gè)鏈接抓取,parse()方法中定義的要抓取什么樣的數據。
當一個(gè)Spider開(kāi)始執行的時(shí)侯,它首先從start_urls()中的第一個(gè)鏈接開(kāi)始發(fā)起懇求網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),然后在callback里處理返回的數據。
Item類(lèi)提供低格的數據,可以理解為數據Model類(lèi)。
Scrapy的Selector類(lèi)基于lxml庫,提供HTML或XML轉換功能。以response對象作為參數生成的Selector實(shí)例即可通過(guò)實(shí)例對象的xpath()方法獲取節點(diǎn)的數據。
接下來(lái)將上一個(gè)Beautiful Soup版的抓取書(shū)籍信息的事例( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總)改寫(xiě)成Scrapy版本。
scrapy startproject book_project
這行命令會(huì )創(chuàng )建一個(gè)名為book_project的項目。
即實(shí)體類(lèi),代碼如下:
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field()
isbn = scrapy.Field()
price = scrapy.Field()
設置這個(gè)Spider的名稱(chēng),允許爬取的域名和從那個(gè)鏈接開(kāi)始:
class BookInfoSpider(scrapy.Spider):
name = "bookinfo"
allowed_domains = ["allitebooks.com", "amazon.com"]
start_urls = [
"http://www.allitebooks.com/security/",
]
def parse(self, response):
# response.xpath('//a[contains(@title, "Last Page →")]/@href').re(r'(\d+)')[0]
num_pages = int(response.xpath('//a[contains(@title, "Last Page →")]/text()').extract_first())
base_url = "http://www.allitebooks.com/security/page/{0}/"
for page in range(1, num_pages):
yield scrapy.Request(base_url.format(page), dont_filter=True, callback=self.parse_page) 查看全部
上周學(xué)習了BeautifulSoup的基礎知識并用它完成了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總),
BeautifulSoup是一個(gè)十分流行的Python網(wǎng)路抓取庫,它提供了一個(gè)基于HTML結構的Python對象。
雖然簡(jiǎn)單易懂,又能非常好的處理HTML數據,
但是相比Scrapy而言網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),BeautifulSoup有一個(gè)最大的缺點(diǎn):慢。
Scrapy 是一個(gè)開(kāi)源的 Python 數據抓取框架,速度快,強大,而且使用簡(jiǎn)單。
來(lái)看一個(gè)官網(wǎng)主頁(yè)上的簡(jiǎn)單并完整的爬蟲(chóng):

雖然只有10行左右的代碼,但是它的確是一個(gè)完整的爬蟲(chóng)服務(wù):
Scrapy所有的懇求都是異步的:
安裝(Mac)
pip install scrapy
其他操作系統請參考完整安裝指導:
Spider類(lèi)想要抒發(fā)的是:如何抓取一個(gè)確定了的網(wǎng)站的數據。比如在start_urls里定義的去那個(gè)鏈接抓取,parse()方法中定義的要抓取什么樣的數據。
當一個(gè)Spider開(kāi)始執行的時(shí)侯,它首先從start_urls()中的第一個(gè)鏈接開(kāi)始發(fā)起懇求網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),然后在callback里處理返回的數據。
Item類(lèi)提供低格的數據,可以理解為數據Model類(lèi)。
Scrapy的Selector類(lèi)基于lxml庫,提供HTML或XML轉換功能。以response對象作為參數生成的Selector實(shí)例即可通過(guò)實(shí)例對象的xpath()方法獲取節點(diǎn)的數據。
接下來(lái)將上一個(gè)Beautiful Soup版的抓取書(shū)籍信息的事例( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總)改寫(xiě)成Scrapy版本。
scrapy startproject book_project
這行命令會(huì )創(chuàng )建一個(gè)名為book_project的項目。
即實(shí)體類(lèi),代碼如下:
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field()
isbn = scrapy.Field()
price = scrapy.Field()
設置這個(gè)Spider的名稱(chēng),允許爬取的域名和從那個(gè)鏈接開(kāi)始:
class BookInfoSpider(scrapy.Spider):
name = "bookinfo"
allowed_domains = ["allitebooks.com", "amazon.com"]
start_urls = [
"http://www.allitebooks.com/security/",
]
def parse(self, response):
# response.xpath('//a[contains(@title, "Last Page →")]/@href').re(r'(\d+)')[0]
num_pages = int(response.xpath('//a[contains(@title, "Last Page →")]/text()').extract_first())
base_url = "http://www.allitebooks.com/security/page/{0}/"
for page in range(1, num_pages):
yield scrapy.Request(base_url.format(page), dont_filter=True, callback=self.parse_page)
從零開(kāi)始基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 412 次瀏覽 ? 2020-07-06 08:01
前節介紹了哪些網(wǎng)路爬蟲(chóng),什么是Scrapy框架并怎樣安裝
本節介紹基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
安裝好Scrapy框架后,就可以基于Scrapy框架開(kāi)發(fā)爬蟲(chóng)項目了?;诳蚣荛_(kāi)發(fā)項目,不需要從零開(kāi)始編撰代碼,只須要把握怎樣使用框架,如何添加與自己應用相關(guān)的代碼即可。
進(jìn)入準備新建爬蟲(chóng)項目的路徑中,使用命令:
scrapy startproject project_name
請用爬蟲(chóng)項目名稱(chēng)替換命令中的project_name爬蟲(chóng)軟件開(kāi)發(fā),例如,本文準備創(chuàng )建一個(gè)爬取新浪網(wǎng)的爬蟲(chóng),取名為sina_spider,則新建爬蟲(chóng)項目的命令為:
scrapy startproject sina_spider
命令運行結果,如下圖所示。
新建爬蟲(chóng)項目
“scrapy startproject sina_spider”命令會(huì )創(chuàng )建包含下述內容的sina_spider目錄,如圖13-5所示。
爬蟲(chóng)文件夾結構
新建好Scrapy爬蟲(chóng)項目后,接下來(lái)就是創(chuàng )建爬蟲(chóng)文件。請先步入sina_spider項目路徑,用命令:
scrapy genspider spider_filename(爬蟲(chóng)文件名) (待爬取的網(wǎng)站域名)
創(chuàng )建爬蟲(chóng)文件。例如,本文的爬蟲(chóng)文件名為:sinaSpider,待爬取的網(wǎng)站域名:,則創(chuàng )建爬蟲(chóng)文件sinaSpider的命令為:
scrapy genspider sinaSpider
現在好多網(wǎng)站都有防爬蟲(chóng)舉措,為了反網(wǎng)站的防爬蟲(chóng)舉措,需要添加user agent信息。請settings.py文件的第19行更改如下所示:
18. # Crawl responsibly by identifying yourself (and your website) on the user-agent
19. import random
20. # user agent 列表
21. USER_AGENT_LIST = [
22. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
23. "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
24. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
25. "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
26. "Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)",
27. "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
28. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0",
29. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0",
30. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0",
31. "Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)",
32. "Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)" ]
33. USER_AGENT = random.choice(USER_AGENT_LIST) # 隨機生成user agent
網(wǎng)站的服務(wù)器中保存一個(gè)robots.txt 文件,其作用是,告訴搜索引擎爬蟲(chóng),本網(wǎng)站哪些目錄下的網(wǎng)頁(yè)不希望被爬取收錄。Scrapy啟動(dòng)后,會(huì )在第一時(shí)間訪(fǎng)問(wèn)網(wǎng)站的 robots.txt 文件,然后決定該網(wǎng)站的爬取范圍。
由于本文的項目并非搜索引擎爬蟲(chóng),而且很有可能我們想要獲取的內容恰恰是被 robots.txt所嚴禁訪(fǎng)問(wèn)的,所以請把settings.py文件的ROBOTSTXT_OBEY值設置為False,表示拒絕遵循Robot合同,如下所示
1. # Obey robots.txt rules
2. ROBOTSTXT_OBEY = False # False表示拒絕遵守Robot協(xié)議
查看由Scrapy生成的sinaSpider.py文件,在SinaspiderSpider類(lèi)中,有一個(gè)parse()方法須要用戶(hù)編撰,如下圖所示
編寫(xiě)parse()方法
Scrapy框架把爬取出來(lái)的網(wǎng)頁(yè)源代碼儲存在response對象中爬蟲(chóng)軟件開(kāi)發(fā),我們只須要對response對象中的網(wǎng)頁(yè)源代碼做解析,提取想要的數據即可。本范例目標是抓取新浪網(wǎng)頁(yè)的新聞的標題和對應的鏈接,如下圖所示。
HTML源代碼
parse()方法的實(shí)現代碼,如下所示
1. # -*- coding: utf-8 -*-
2. import scrapy
3.
4. class SinaspiderSpider(scrapy.Spider):
5. name = 'sinaSpider'
6. allowed_domains = ['www.sina.com.cn']
7. start_urls = ['http://www.sina.com.cn/']
8.
9. def parse(self, response):
10. data_list = [] #用于存儲解析到的數據
11. #解析HTML源代碼,定位新聞內容
12. lis = response.xpath("//div[@class='top_newslist']/ul[@class='list-a news_top']//li")
13. #將新聞主題和超鏈接解析出來(lái)并整理到列表中
14. for li in lis:
15. titles = li.xpath(".//a/text()")
16. linkes = li.xpath(".//a/@href")
17. for title, link in zip(titles, linkes):
18. #將新聞主題和對應的超鏈接組合成字典
19. data_dict = {'標題': title.extract(), '鏈接': link.extract()}
20. #將字典數據存儲到data_list這個(gè)列表中
21. data_list.append(data_dict)
22. return data_list
parse()方法在解析HTML源代碼時(shí),使用了XPath路徑表達式。XPath是一門(mén)在HTML/XML文檔中查找信息的語(yǔ)言,常用于在網(wǎng)頁(yè)HTML源代碼中,查找特定標簽里的數據。在網(wǎng)絡(luò )爬蟲(chóng)中使用XPath,只須要把握 XPath路徑表達式即可。XPath 使用路徑表達式來(lái)選定 HTML/XML文檔中的節點(diǎn)或則節點(diǎn)集。
parse()方法編撰好后,就可以運行爬蟲(chóng)程序并保存抓取數據了。用命令:
scrapy crawl 爬蟲(chóng)文件名 –o 保存數據文件名.[csv|json|xml]
保存數據的文件格式可以是csv 或 json 或 xml,本例的爬蟲(chóng)文件名為:sinaSpider.py,數據儲存選擇csv格式,命令為:
scrapy crawl sinaSpider -o sinaNews.csv
運行療效,如下圖所示
運行爬蟲(chóng)
到此,本例基于Scrapy框架從零開(kāi)始實(shí)現了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)程序,爬取了新浪網(wǎng)頁(yè)并從中解析出新聞的標題和對應的超鏈接,最后把解析出的數據保存為csv文件供后續使用。 查看全部

前節介紹了哪些網(wǎng)路爬蟲(chóng),什么是Scrapy框架并怎樣安裝
本節介紹基于Scrapy框架的網(wǎng)路爬蟲(chóng)開(kāi)發(fā)流程
安裝好Scrapy框架后,就可以基于Scrapy框架開(kāi)發(fā)爬蟲(chóng)項目了?;诳蚣荛_(kāi)發(fā)項目,不需要從零開(kāi)始編撰代碼,只須要把握怎樣使用框架,如何添加與自己應用相關(guān)的代碼即可。
進(jìn)入準備新建爬蟲(chóng)項目的路徑中,使用命令:
scrapy startproject project_name
請用爬蟲(chóng)項目名稱(chēng)替換命令中的project_name爬蟲(chóng)軟件開(kāi)發(fā),例如,本文準備創(chuàng )建一個(gè)爬取新浪網(wǎng)的爬蟲(chóng),取名為sina_spider,則新建爬蟲(chóng)項目的命令為:
scrapy startproject sina_spider
命令運行結果,如下圖所示。

新建爬蟲(chóng)項目
“scrapy startproject sina_spider”命令會(huì )創(chuàng )建包含下述內容的sina_spider目錄,如圖13-5所示。

爬蟲(chóng)文件夾結構
新建好Scrapy爬蟲(chóng)項目后,接下來(lái)就是創(chuàng )建爬蟲(chóng)文件。請先步入sina_spider項目路徑,用命令:
scrapy genspider spider_filename(爬蟲(chóng)文件名) (待爬取的網(wǎng)站域名)
創(chuàng )建爬蟲(chóng)文件。例如,本文的爬蟲(chóng)文件名為:sinaSpider,待爬取的網(wǎng)站域名:,則創(chuàng )建爬蟲(chóng)文件sinaSpider的命令為:
scrapy genspider sinaSpider
現在好多網(wǎng)站都有防爬蟲(chóng)舉措,為了反網(wǎng)站的防爬蟲(chóng)舉措,需要添加user agent信息。請settings.py文件的第19行更改如下所示:
18. # Crawl responsibly by identifying yourself (and your website) on the user-agent
19. import random
20. # user agent 列表
21. USER_AGENT_LIST = [
22. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
23. "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
24. "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
25. "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
26. "Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)",
27. "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
28. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0",
29. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0",
30. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0",
31. "Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)",
32. "Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)" ]
33. USER_AGENT = random.choice(USER_AGENT_LIST) # 隨機生成user agent
網(wǎng)站的服務(wù)器中保存一個(gè)robots.txt 文件,其作用是,告訴搜索引擎爬蟲(chóng),本網(wǎng)站哪些目錄下的網(wǎng)頁(yè)不希望被爬取收錄。Scrapy啟動(dòng)后,會(huì )在第一時(shí)間訪(fǎng)問(wèn)網(wǎng)站的 robots.txt 文件,然后決定該網(wǎng)站的爬取范圍。
由于本文的項目并非搜索引擎爬蟲(chóng),而且很有可能我們想要獲取的內容恰恰是被 robots.txt所嚴禁訪(fǎng)問(wèn)的,所以請把settings.py文件的ROBOTSTXT_OBEY值設置為False,表示拒絕遵循Robot合同,如下所示
1. # Obey robots.txt rules
2. ROBOTSTXT_OBEY = False # False表示拒絕遵守Robot協(xié)議
查看由Scrapy生成的sinaSpider.py文件,在SinaspiderSpider類(lèi)中,有一個(gè)parse()方法須要用戶(hù)編撰,如下圖所示

編寫(xiě)parse()方法
Scrapy框架把爬取出來(lái)的網(wǎng)頁(yè)源代碼儲存在response對象中爬蟲(chóng)軟件開(kāi)發(fā),我們只須要對response對象中的網(wǎng)頁(yè)源代碼做解析,提取想要的數據即可。本范例目標是抓取新浪網(wǎng)頁(yè)的新聞的標題和對應的鏈接,如下圖所示。

HTML源代碼
parse()方法的實(shí)現代碼,如下所示
1. # -*- coding: utf-8 -*-
2. import scrapy
3.
4. class SinaspiderSpider(scrapy.Spider):
5. name = 'sinaSpider'
6. allowed_domains = ['www.sina.com.cn']
7. start_urls = ['http://www.sina.com.cn/']
8.
9. def parse(self, response):
10. data_list = [] #用于存儲解析到的數據
11. #解析HTML源代碼,定位新聞內容
12. lis = response.xpath("//div[@class='top_newslist']/ul[@class='list-a news_top']//li")
13. #將新聞主題和超鏈接解析出來(lái)并整理到列表中
14. for li in lis:
15. titles = li.xpath(".//a/text()")
16. linkes = li.xpath(".//a/@href")
17. for title, link in zip(titles, linkes):
18. #將新聞主題和對應的超鏈接組合成字典
19. data_dict = {'標題': title.extract(), '鏈接': link.extract()}
20. #將字典數據存儲到data_list這個(gè)列表中
21. data_list.append(data_dict)
22. return data_list
parse()方法在解析HTML源代碼時(shí),使用了XPath路徑表達式。XPath是一門(mén)在HTML/XML文檔中查找信息的語(yǔ)言,常用于在網(wǎng)頁(yè)HTML源代碼中,查找特定標簽里的數據。在網(wǎng)絡(luò )爬蟲(chóng)中使用XPath,只須要把握 XPath路徑表達式即可。XPath 使用路徑表達式來(lái)選定 HTML/XML文檔中的節點(diǎn)或則節點(diǎn)集。
parse()方法編撰好后,就可以運行爬蟲(chóng)程序并保存抓取數據了。用命令:
scrapy crawl 爬蟲(chóng)文件名 –o 保存數據文件名.[csv|json|xml]
保存數據的文件格式可以是csv 或 json 或 xml,本例的爬蟲(chóng)文件名為:sinaSpider.py,數據儲存選擇csv格式,命令為:
scrapy crawl sinaSpider -o sinaNews.csv
運行療效,如下圖所示

運行爬蟲(chóng)
到此,本例基于Scrapy框架從零開(kāi)始實(shí)現了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)程序,爬取了新浪網(wǎng)頁(yè)并從中解析出新聞的標題和對應的超鏈接,最后把解析出的數據保存為csv文件供后續使用。
爬蟲(chóng)框架(scrapy構架)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 588 次瀏覽 ? 2020-07-03 08:00
scrapy主要包括了以下組件: 1.)引擎(scrapy):用來(lái)處理整個(gè)系統的數據流,觸發(fā)事務(wù)(框架核心) 2.)調度器(Scheduler):用來(lái)接受引擎發(fā)過(guò)來(lái)的懇求,壓入隊列中,并在引擎再度懇求的時(shí)侯返回,可以想像成一個(gè)url(抓取網(wǎng)頁(yè)的網(wǎng)址或則說(shuō)鏈接)的優(yōu)先隊列,由它來(lái)決定下一個(gè)要抓取的網(wǎng)址是哪些,同時(shí)除去重復的網(wǎng)址。 3.)下載器(Downloader):用于下載網(wǎng)頁(yè)的內容,并將網(wǎng)頁(yè)內容返回給蜘蛛(Scrapy下載器是構建在twisted這個(gè)高效的異步模型上的) 4.)爬蟲(chóng)(Spiders):爬蟲(chóng)是主要干活的,用于從特定的網(wǎng)頁(yè)中提取自己想要的信息,即所謂的實(shí)體(item)。用戶(hù)也可以從中提取到鏈接,讓Scrapy繼續抓取下一個(gè)頁(yè)面。 5.)項目管線(xiàn)(Pipeline):負責處理爬蟲(chóng)從網(wǎng)頁(yè)中抽取的實(shí)體,主要的功能是持久化實(shí)體、清除不需要的信息。當頁(yè)面被爬蟲(chóng)解析后,將被發(fā)送到項目管線(xiàn),并經(jīng)過(guò)幾個(gè)特定的順序處理數據。 (只有當調度器中不存在任何request時(shí),整個(gè)程序就會(huì )停止。(對于下載失敗的url,Scrapy也會(huì )重新下載))
前置要求: pip下載scrapy模塊 yum下載tree包
-確定url地址; -獲取頁(yè)面信息;(urllib,requests) -解析頁(yè)面提取須要的信息;(xpath,bs4,正則表達時(shí)) -保存到本地(scv,json,pymysql,redis) -清洗數據(刪除不必要的內容------正則表達式) -分析數據(詞云wordcloud,jieba)
-確定url地址(spider) -獲取頁(yè)面信息(Downloader) -解析頁(yè)面提取須要的信息(spider) -保存到本地(pipeline)
scrapy1.6.0
1.工程創(chuàng )建 1.)命令行在當前目錄下創(chuàng )建mySpider
scrapy startproject mySpider
2.)創(chuàng )建成功后,進(jìn)入mySpider ,tree查看
cd mySpider tree
2.創(chuàng )建一個(gè)爬蟲(chóng)
#scrapy genspider 項目名 url scrapy genspider mooc ‘’
3.定義爬取的items內容(items.py)
class CourseItem(scrapy.Item):
#課程標題 title=scrapy.Field() #課程的url地址 url=scrapy.Field() #課程圖片的url地址 image_url=scrapy.Field() #課程的描述 introduction=scrapy.Field() #學(xué)習人數 student=scrapy.Field()
4.編寫(xiě)spider代碼,解析 4.1確定url地址,提取頁(yè)面須要的信息(mooc.py)
class MoocSpider(scrapy,spider):
#name用于區別爬蟲(chóng),必須惟一 name=‘mooc’ #允許爬取的域名,其他網(wǎng)站的頁(yè)面直接跳過(guò) allowd_domains=[‘’,‘’] #爬蟲(chóng)開(kāi)啟時(shí)第一個(gè)裝入調度器的url地址 start_urls=[‘’] #被調用時(shí),每個(gè)新的url完成下載后爬蟲(chóng)框架,返回一個(gè)響應對象 #下面的方式負責將響應的數據剖析,提取出須要的數據items以及生成下一步須要處理的url地址懇求; def parser(self,response):
##用來(lái)檢查代碼是否達到指定位置,并拿來(lái)調試并解析頁(yè)面信息; #from scrapy.shell import inspect_response #inspect_response(response,self) #1.)實(shí)例化對象,CourseItem course=CourseItem() #分析響應的內容 #scrapy剖析頁(yè)面使用的是xpath方式 #2.)獲取每位課程的信息 courseDetails=course.xpath(’.//div[@class=“course-card-container”]’) for courseDetail in courseDetails:
#爬取新的網(wǎng)站, Scrapy上面進(jìn)行調試(parse命令logging) course[‘title’] = courseDetail.xpath(’.//h3[@class=“course-card-name”]/text()’).extract()[0] #學(xué)習人數 course[‘student’] = courseDetail.xpath(’.//span/text()’).extract()[1] #課程描述: course[‘introduction’] = courseDetail.xpath(".//p[@class=‘course-card-desc’]/text()").extract()[0] #課程鏈接, h獲取/learn/9 ====》 course[‘url’] = “” + courseDetail.xpath(’.//a/@href’).extract()[0] #課程的圖片url: course[‘image_url’] = ‘http:’ + courseDetail.xpath(’.//img/@src’).extract()[0] yield course #url跟進(jìn),獲取下一步是否有鏈接;href url=response.xpath(’.//a[contains[text(),“下一頁(yè)”]/@href’)[0].extract() if url:
#構建新的url page=‘’+url yield scrapy.Request(page,callback=slef.parse)
4.2保存我們提取的信息(文件格式:scv爬蟲(chóng)框架,json,pymysql)(pipeline.py) 如果多線(xiàn)程,記得在settings.py中分配多個(gè)管線(xiàn)并設置優(yōu)先級:
(1).將爬取的信息保存成json格式
class MyspiderPipeline(object):
def init(self):
self.f=open(Moocfilename,‘w’) #Moocfilename是寫(xiě)在settings.py里的文件名,寫(xiě)在setting.py是因為便捷更改
def process_item(self,item,spider):
#默認傳過(guò)來(lái)的格式是json格式 import json #讀取item中的數據,并轉化為json格式 line=json.dumps(dict(item),ensure_ascii=False,indent=4) self.f.write(line+’\n’) #一定要返回給調度器 return item
def close_spider(self,spider):
self.f.close()
(2).保存為scv格式
class CsvPipeline(object):
def init(self):
self.f=open(’'mooc.csv",‘w’)
def process_item(self,item,spider):
item=dict(item) self.f.write("{0}:{1}:{2}\n".format(item[‘title’] , item[‘student’] , item[‘url’])) return item
def close_spider(self,spider):
self.f.close()
(3).將爬取的信息保存到數據庫中 首先打開(kāi)數據庫創(chuàng )建mooc表
class MysqlPipeline(object):
def init(self):
self.conn=pymysql.connect( host=‘localhost’, user=‘root’, password=‘redhat’, db=‘Mooc’, charset=‘utf8’, ) self.cursor=self.conn.cursor()
def process_item(self,item,spider):
item=dict(item) info=(item[’‘item"] , item[“url”] , item[“image_url”] , item[“introduction”] , item[“student”]) insert_sqil="insert into moocinfo values(’%s’ , ‘%s’ , ‘%s’, ‘%s’ , ‘%s’); " %(info) self.cursor.execute(insert_sqil) mit() return item
def open_spider(self,spider):
create_sqli=“create table if not exists moocinfo (title varchar(50),url varchar(200), image_url varchar(200), introduction varchar(500), student int)” self.cursor.execute(create_sqli)
def close_spider(self,spider):
self.cursor.close() self.conn.close()
(4).通過(guò)爬取的圖片鏈接下載圖片
class ImagePipeline(object):
def get_media_requests(self,item,info):
#返回一個(gè)request請求,包含圖片的url
yield scrapy.Request(item['image_url'])
def item_conpleted(self,results,item,info):
#獲取下載的地址
image_xpath=[x['path'] for ok , x in results if ok]
if not image_path:
raise Exception('不包含圖片')
else:
return item
1.策略一:設置download_delay –作用:設置下載的等待時(shí)間,大規模集中的訪(fǎng)問(wèn)對服務(wù)器的影響最大,相當于短時(shí)間內減小服務(wù)器的負載 –缺點(diǎn):下載等待時(shí)間長(cháng),不能滿(mǎn)足段時(shí)間大規模抓取的要求,太短則大大降低了被ban的機率
2.策略二:禁止cookies –cookie有時(shí)也用作復數方式cookies,指個(gè)別網(wǎng)站為了分辨用戶(hù)的身分,進(jìn)行session跟蹤而存儲在用戶(hù)本地終端上的數據(通常經(jīng)過(guò)加密)。 –作用:禁止cookies也就避免了可能使用cookies辨識爬蟲(chóng)軌跡的網(wǎng)站得逞 –實(shí)現:COOKIES_ENABLES=False
3.策略三:使用user_agent池(拓展:用戶(hù)代理中間件) –為什么要使用?scrapy本身是使用Scrapy/0.22.2來(lái)表明自己的身分。這也就曝露了自己是爬蟲(chóng)的信息。 –user agent ,是指包含瀏覽器信息,操作系統信息等的一個(gè)字符串,也稱(chēng)之為一種特殊的網(wǎng)路合同。服務(wù)器通過(guò)它判定當前的訪(fǎng)問(wèn)對象是瀏覽器,郵件客戶(hù)端還是爬蟲(chóng)。
4.策略四:使用代理中間件 –web server應對爬蟲(chóng)的策略之一就是直接將你的ip或則是整個(gè)ip段都封掉嚴禁訪(fǎng)問(wèn),這時(shí)候,當ip封掉后,轉換到其他的ip繼續訪(fǎng)問(wèn)即可。
5.策略五:分布式爬蟲(chóng)Scrapy+redis+mysql # 多進(jìn)程 –Scrapy-Redis則是一個(gè)基于Redis的Scrapy分布式組件。它借助Redis對用于爬取的懇求(Requests)進(jìn)行儲存和調度(Schedule),并對爬取形成rapy一些比較關(guān)鍵的代碼,將Scrapy弄成一個(gè)可以在多個(gè)主機上同時(shí)運行的分布式爬蟲(chóng)。
米鼠網(wǎng)自創(chuàng )立以來(lái)仍然專(zhuān)注于從事政府采購、軟件項目、人才外包、獵頭服務(wù)、綜合項目等,始終秉持“專(zhuān)業(yè)的服務(wù),易用的產(chǎn)品”的經(jīng)營(yíng)理念,以“提供高品質(zhì)的服務(wù)、滿(mǎn)足顧客的需求、攜手共創(chuàng )多贏(yíng)”為企業(yè)目標,為中國境內企業(yè)提供國際化、專(zhuān)業(yè)化、個(gè)性化、的軟件項目解決方案,我司擁有一流的項目總監團隊,具備過(guò)硬的軟件項目設計和施行能力,為全省不同行業(yè)顧客提供優(yōu)質(zhì)的產(chǎn)品和服務(wù),得到了顧客的廣泛贊揚。
如有侵權請聯(lián)系郵箱() 查看全部
1.scrapy構架流程:

scrapy主要包括了以下組件: 1.)引擎(scrapy):用來(lái)處理整個(gè)系統的數據流,觸發(fā)事務(wù)(框架核心) 2.)調度器(Scheduler):用來(lái)接受引擎發(fā)過(guò)來(lái)的懇求,壓入隊列中,并在引擎再度懇求的時(shí)侯返回,可以想像成一個(gè)url(抓取網(wǎng)頁(yè)的網(wǎng)址或則說(shuō)鏈接)的優(yōu)先隊列,由它來(lái)決定下一個(gè)要抓取的網(wǎng)址是哪些,同時(shí)除去重復的網(wǎng)址。 3.)下載器(Downloader):用于下載網(wǎng)頁(yè)的內容,并將網(wǎng)頁(yè)內容返回給蜘蛛(Scrapy下載器是構建在twisted這個(gè)高效的異步模型上的) 4.)爬蟲(chóng)(Spiders):爬蟲(chóng)是主要干活的,用于從特定的網(wǎng)頁(yè)中提取自己想要的信息,即所謂的實(shí)體(item)。用戶(hù)也可以從中提取到鏈接,讓Scrapy繼續抓取下一個(gè)頁(yè)面。 5.)項目管線(xiàn)(Pipeline):負責處理爬蟲(chóng)從網(wǎng)頁(yè)中抽取的實(shí)體,主要的功能是持久化實(shí)體、清除不需要的信息。當頁(yè)面被爬蟲(chóng)解析后,將被發(fā)送到項目管線(xiàn),并經(jīng)過(guò)幾個(gè)特定的順序處理數據。 (只有當調度器中不存在任何request時(shí),整個(gè)程序就會(huì )停止。(對于下載失敗的url,Scrapy也會(huì )重新下載))
前置要求: pip下載scrapy模塊 yum下載tree包
-確定url地址; -獲取頁(yè)面信息;(urllib,requests) -解析頁(yè)面提取須要的信息;(xpath,bs4,正則表達時(shí)) -保存到本地(scv,json,pymysql,redis) -清洗數據(刪除不必要的內容------正則表達式) -分析數據(詞云wordcloud,jieba)
-確定url地址(spider) -獲取頁(yè)面信息(Downloader) -解析頁(yè)面提取須要的信息(spider) -保存到本地(pipeline)
scrapy1.6.0
1.工程創(chuàng )建 1.)命令行在當前目錄下創(chuàng )建mySpider
scrapy startproject mySpider
2.)創(chuàng )建成功后,進(jìn)入mySpider ,tree查看
cd mySpider tree

2.創(chuàng )建一個(gè)爬蟲(chóng)
#scrapy genspider 項目名 url scrapy genspider mooc ‘’
3.定義爬取的items內容(items.py)
class CourseItem(scrapy.Item):
#課程標題 title=scrapy.Field() #課程的url地址 url=scrapy.Field() #課程圖片的url地址 image_url=scrapy.Field() #課程的描述 introduction=scrapy.Field() #學(xué)習人數 student=scrapy.Field()
4.編寫(xiě)spider代碼,解析 4.1確定url地址,提取頁(yè)面須要的信息(mooc.py)
class MoocSpider(scrapy,spider):
#name用于區別爬蟲(chóng),必須惟一 name=‘mooc’ #允許爬取的域名,其他網(wǎng)站的頁(yè)面直接跳過(guò) allowd_domains=[‘’,‘’] #爬蟲(chóng)開(kāi)啟時(shí)第一個(gè)裝入調度器的url地址 start_urls=[‘’] #被調用時(shí),每個(gè)新的url完成下載后爬蟲(chóng)框架,返回一個(gè)響應對象 #下面的方式負責將響應的數據剖析,提取出須要的數據items以及生成下一步須要處理的url地址懇求; def parser(self,response):
##用來(lái)檢查代碼是否達到指定位置,并拿來(lái)調試并解析頁(yè)面信息; #from scrapy.shell import inspect_response #inspect_response(response,self) #1.)實(shí)例化對象,CourseItem course=CourseItem() #分析響應的內容 #scrapy剖析頁(yè)面使用的是xpath方式 #2.)獲取每位課程的信息 courseDetails=course.xpath(’.//div[@class=“course-card-container”]’) for courseDetail in courseDetails:
#爬取新的網(wǎng)站, Scrapy上面進(jìn)行調試(parse命令logging) course[‘title’] = courseDetail.xpath(’.//h3[@class=“course-card-name”]/text()’).extract()[0] #學(xué)習人數 course[‘student’] = courseDetail.xpath(’.//span/text()’).extract()[1] #課程描述: course[‘introduction’] = courseDetail.xpath(".//p[@class=‘course-card-desc’]/text()").extract()[0] #課程鏈接, h獲取/learn/9 ====》 course[‘url’] = “” + courseDetail.xpath(’.//a/@href’).extract()[0] #課程的圖片url: course[‘image_url’] = ‘http:’ + courseDetail.xpath(’.//img/@src’).extract()[0] yield course #url跟進(jìn),獲取下一步是否有鏈接;href url=response.xpath(’.//a[contains[text(),“下一頁(yè)”]/@href’)[0].extract() if url:
#構建新的url page=‘’+url yield scrapy.Request(page,callback=slef.parse)
4.2保存我們提取的信息(文件格式:scv爬蟲(chóng)框架,json,pymysql)(pipeline.py) 如果多線(xiàn)程,記得在settings.py中分配多個(gè)管線(xiàn)并設置優(yōu)先級:

(1).將爬取的信息保存成json格式
class MyspiderPipeline(object):
def init(self):
self.f=open(Moocfilename,‘w’) #Moocfilename是寫(xiě)在settings.py里的文件名,寫(xiě)在setting.py是因為便捷更改
def process_item(self,item,spider):
#默認傳過(guò)來(lái)的格式是json格式 import json #讀取item中的數據,并轉化為json格式 line=json.dumps(dict(item),ensure_ascii=False,indent=4) self.f.write(line+’\n’) #一定要返回給調度器 return item
def close_spider(self,spider):
self.f.close()
(2).保存為scv格式
class CsvPipeline(object):
def init(self):
self.f=open(’'mooc.csv",‘w’)
def process_item(self,item,spider):
item=dict(item) self.f.write("{0}:{1}:{2}\n".format(item[‘title’] , item[‘student’] , item[‘url’])) return item
def close_spider(self,spider):
self.f.close()
(3).將爬取的信息保存到數據庫中 首先打開(kāi)數據庫創(chuàng )建mooc表
class MysqlPipeline(object):
def init(self):
self.conn=pymysql.connect( host=‘localhost’, user=‘root’, password=‘redhat’, db=‘Mooc’, charset=‘utf8’, ) self.cursor=self.conn.cursor()
def process_item(self,item,spider):
item=dict(item) info=(item[’‘item"] , item[“url”] , item[“image_url”] , item[“introduction”] , item[“student”]) insert_sqil="insert into moocinfo values(’%s’ , ‘%s’ , ‘%s’, ‘%s’ , ‘%s’); " %(info) self.cursor.execute(insert_sqil) mit() return item
def open_spider(self,spider):
create_sqli=“create table if not exists moocinfo (title varchar(50),url varchar(200), image_url varchar(200), introduction varchar(500), student int)” self.cursor.execute(create_sqli)
def close_spider(self,spider):
self.cursor.close() self.conn.close()
(4).通過(guò)爬取的圖片鏈接下載圖片
class ImagePipeline(object):
def get_media_requests(self,item,info):
#返回一個(gè)request請求,包含圖片的url
yield scrapy.Request(item['image_url'])
def item_conpleted(self,results,item,info):
#獲取下載的地址
image_xpath=[x['path'] for ok , x in results if ok]
if not image_path:
raise Exception('不包含圖片')
else:
return item
1.策略一:設置download_delay –作用:設置下載的等待時(shí)間,大規模集中的訪(fǎng)問(wèn)對服務(wù)器的影響最大,相當于短時(shí)間內減小服務(wù)器的負載 –缺點(diǎn):下載等待時(shí)間長(cháng),不能滿(mǎn)足段時(shí)間大規模抓取的要求,太短則大大降低了被ban的機率
2.策略二:禁止cookies –cookie有時(shí)也用作復數方式cookies,指個(gè)別網(wǎng)站為了分辨用戶(hù)的身分,進(jìn)行session跟蹤而存儲在用戶(hù)本地終端上的數據(通常經(jīng)過(guò)加密)。 –作用:禁止cookies也就避免了可能使用cookies辨識爬蟲(chóng)軌跡的網(wǎng)站得逞 –實(shí)現:COOKIES_ENABLES=False
3.策略三:使用user_agent池(拓展:用戶(hù)代理中間件) –為什么要使用?scrapy本身是使用Scrapy/0.22.2來(lái)表明自己的身分。這也就曝露了自己是爬蟲(chóng)的信息。 –user agent ,是指包含瀏覽器信息,操作系統信息等的一個(gè)字符串,也稱(chēng)之為一種特殊的網(wǎng)路合同。服務(wù)器通過(guò)它判定當前的訪(fǎng)問(wèn)對象是瀏覽器,郵件客戶(hù)端還是爬蟲(chóng)。
4.策略四:使用代理中間件 –web server應對爬蟲(chóng)的策略之一就是直接將你的ip或則是整個(gè)ip段都封掉嚴禁訪(fǎng)問(wèn),這時(shí)候,當ip封掉后,轉換到其他的ip繼續訪(fǎng)問(wèn)即可。
5.策略五:分布式爬蟲(chóng)Scrapy+redis+mysql # 多進(jìn)程 –Scrapy-Redis則是一個(gè)基于Redis的Scrapy分布式組件。它借助Redis對用于爬取的懇求(Requests)進(jìn)行儲存和調度(Schedule),并對爬取形成rapy一些比較關(guān)鍵的代碼,將Scrapy弄成一個(gè)可以在多個(gè)主機上同時(shí)運行的分布式爬蟲(chóng)。
米鼠網(wǎng)自創(chuàng )立以來(lái)仍然專(zhuān)注于從事政府采購、軟件項目、人才外包、獵頭服務(wù)、綜合項目等,始終秉持“專(zhuān)業(yè)的服務(wù),易用的產(chǎn)品”的經(jīng)營(yíng)理念,以“提供高品質(zhì)的服務(wù)、滿(mǎn)足顧客的需求、攜手共創(chuàng )多贏(yíng)”為企業(yè)目標,為中國境內企業(yè)提供國際化、專(zhuān)業(yè)化、個(gè)性化、的軟件項目解決方案,我司擁有一流的項目總監團隊,具備過(guò)硬的軟件項目設計和施行能力,為全省不同行業(yè)顧客提供優(yōu)質(zhì)的產(chǎn)品和服務(wù),得到了顧客的廣泛贊揚。

如有侵權請聯(lián)系郵箱()
基于Scrapy框架的分布式網(wǎng)路爬蟲(chóng)實(shí)現
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 279 次瀏覽 ? 2020-05-14 08:09
2.2 用戶(hù)登入 由于網(wǎng)站對于旅客的訪(fǎng)問(wèn)有限制,為了爬取所需信息,必須在程序中實(shí)現用戶(hù)登陸,其原 理就是能獲取到有效的本地 cookie,并借助該 cookie 進(jìn)行網(wǎng)站訪(fǎng)問(wèn),除了通常還能用第三方庫 進(jìn)行圖象辨識的驗證方法外,一般采用瀏覽器中自動(dòng)登入,通過(guò)網(wǎng)路工具截取有效的 cookie, 然后在爬蟲(chóng)生成 request 時(shí)附送上 cookie。 2.3 url 的去重 龍源期刊網(wǎng) scrapy_redis 有一個(gè) dupefilter 文件中包含 RFPDupeFilter 類(lèi)用于過(guò)濾新增的 url,可以在該 類(lèi) request_seen 中借助 redis 的 key 的查找功能,如果所爬取的任務(wù)數以?xún)|計則建議 Bloomfilter 去重的方法對于 URL 的儲存和操作方法進(jìn)行優(yōu)化,雖然該方法會(huì )導致大于萬(wàn)分之一的過(guò)濾遺 失率。 2.4 數據寫(xiě)入 選擇非關(guān)系性數據庫 MongoDB 作為硬碟數據庫與 scrapy 進(jìn)行搭配使用,在 pipeline 中對 item 數據進(jìn)行 MongoDB 的寫(xiě)入操作。 3 基本實(shí)現步驟 配置:Windows7 64-bit、Python:2.7.11、 Anaconda 4.0.0 (64-bit)、IDE:Pycharm 3.4.1、Scrapy:1.3.2Redis:X64-3.2、MongoDB:3.2.12 代碼實(shí)現須要對幾個(gè)文件進(jìn)行設置和編撰:items、settings、spiders、pipelines。
Items:這是一個(gè)爬取數據的基礎數據結構類(lèi),由其來(lái)儲存爬蟲(chóng)爬取的鍵值性數據,關(guān)鍵 的就是這條句子:_id = Field() _id 表示的生成一個(gè)數據對象,在 Items 中可以按照須要設定 多個(gè)數據對象。 Settings:ITEM_PIPELINES 該參數決定了 item 的處理方式;DOWNLOAD_DELAY 這個(gè) 是下載的間隔時(shí)間;SCHEDULER 指定作為總的任務(wù)協(xié)調器的類(lèi); SCHEDULER_QUEUE_CLASS 這個(gè)參數是設定處理 URL 的隊列的工作模式一共有四種,一般 選用 SpiderSimpleQueue 即可。 spiders:該文件就是爬蟲(chóng)主要功能的實(shí)現,首先設定該爬蟲(chóng)的基本信息:name、domain、 redis_key、start_urls。爬蟲(chóng)的第一步都是執行方式 start_requests,其中核心句子 yield Request (url,callback)用以按照 url 產(chǎn)生一個(gè) request 并且將 response 結果回傳給 callback 方法。 callback 的方式中通常借助 xpath 或者正則表達式對 response 中包含的 html 代碼進(jìn)行解析,產(chǎn) 生所須要的數據以及新的任務(wù) url。
pipelines:該文件作為數據處理、存儲的代碼段分布式爬蟲(chóng)框架,將在 items 數據被創(chuàng )建后被調用,其中 process_item 的方式就是被調用的方式,所以一定要將其重畫(huà),根據實(shí)際須要把數據借助方式 dict()轉化為字典數據,最后寫(xiě)入 MongoDB。 完成編撰后,在布署的時(shí)侯,start_url 的隊列只能是第一個(gè)運行的爬蟲(chóng)進(jìn)行初始化,后續 運行的爬蟲(chóng)只能是把新的 url 進(jìn)行寫(xiě)入不能對其進(jìn)行再度初始化,部署爬蟲(chóng)的步驟也很簡(jiǎn)單, 只須要把相關(guān)的代碼拷貝到目標筆記本上,讓后 cmd 命令步入 spiders 的文件夾,運行命令 scrapy crawl XXXX,其中 XXXX 就是爬蟲(chóng)的名子,就完成了爬蟲(chóng)的布署和運行了。 龍源期刊網(wǎng) 4 結語(yǔ) 爬蟲(chóng)的實(shí)現,除了基本的步驟和參數設置之外,需要開(kāi)發(fā)者按照實(shí)際網(wǎng)站以及數據情況, 針對性的對爬取的策略、數據的去重、數據篩選進(jìn)行處理,對于爬蟲(chóng)的性能進(jìn)行有效優(yōu)化,為 之后的數據剖析做好良好的數據打算。同時(shí),根據須要可以考慮時(shí)間的誘因加入到數據結構 中,這就要求爬蟲(chóng)還能通過(guò)數據的時(shí)間去進(jìn)行增量爬取。 參考文獻 [1]使用 redis 如何實(shí)現一個(gè)網(wǎng)絡(luò )分布式爬蟲(chóng)[OL].http: //www.oschina.net/code/snippet_209440_20495/. [2]scrapy_redis 的使用解讀[OL].http://www.cnblogs.com/kylinlin/p/5198233.html.http: //blog.csdn.net/u012150179/art 查看全部
龍源期刊網(wǎng) 基于 Scrapy 框架的分布式網(wǎng)路爬蟲(chóng)實(shí)現 作者:陶興海 來(lái)源:《電子技術(shù)與軟件工程》2017 年第 11 期 摘 要按照互聯(lián)網(wǎng)實(shí)際情況,提出分布式爬蟲(chóng)模型,基于 Scrapy 框架,進(jìn)行代碼實(shí)現,且 該開(kāi)發(fā)方法可以迅速進(jìn)行對不同主題的數據爬取的移植,滿(mǎn)足不同專(zhuān)業(yè)方向的基于互聯(lián)網(wǎng)大數 據剖析須要。 【關(guān)鍵詞】網(wǎng)絡(luò )爬蟲(chóng) Scrapy-redis 分布式 1 基本概念 分布式爬蟲(chóng):分布式方法是以共同爬取為目標,形成多爬蟲(chóng)協(xié)同工作的模式,每個(gè)爬蟲(chóng)需 要獨立完成單項爬取任務(wù),下載網(wǎng)頁(yè)并保存。 Scrapy-redis:一個(gè)三方的基于 redis 數據庫實(shí)現的分布式方法,配合 scrapy 爬蟲(chóng)框架讓 用,讓 scrapy 具有了分布式爬取的功能。 2 分布式爬蟲(chóng)技術(shù)方案 Scrapy-redis 分布式爬蟲(chóng)的基本設計理念為主從模式,由作為主控端負責所有網(wǎng)絡(luò )子爬蟲(chóng) 的管理,子爬蟲(chóng)只須要從主控端那兒接收任務(wù)分布式爬蟲(chóng)框架,并把新生成任務(wù)遞交給主控端,在整個(gè)爬取的 過(guò)程中毋須與其他爬蟲(chóng)通訊。 主要有幾個(gè)技術(shù)關(guān)鍵點(diǎn): 2.1 子爬蟲(chóng)爬取任務(wù)的分發(fā) 通過(guò)在主控端安裝一個(gè) redis 數據庫,維護統一的任務(wù)列表,子爬蟲(chóng)每次聯(lián)接 redis 庫調用 lpop()方法,生成一個(gè)任務(wù),并生成一個(gè) request,接下去就是就像通常爬蟲(chóng)工作。
2.2 用戶(hù)登入 由于網(wǎng)站對于旅客的訪(fǎng)問(wèn)有限制,為了爬取所需信息,必須在程序中實(shí)現用戶(hù)登陸,其原 理就是能獲取到有效的本地 cookie,并借助該 cookie 進(jìn)行網(wǎng)站訪(fǎng)問(wèn),除了通常還能用第三方庫 進(jìn)行圖象辨識的驗證方法外,一般采用瀏覽器中自動(dòng)登入,通過(guò)網(wǎng)路工具截取有效的 cookie, 然后在爬蟲(chóng)生成 request 時(shí)附送上 cookie。 2.3 url 的去重 龍源期刊網(wǎng) scrapy_redis 有一個(gè) dupefilter 文件中包含 RFPDupeFilter 類(lèi)用于過(guò)濾新增的 url,可以在該 類(lèi) request_seen 中借助 redis 的 key 的查找功能,如果所爬取的任務(wù)數以?xún)|計則建議 Bloomfilter 去重的方法對于 URL 的儲存和操作方法進(jìn)行優(yōu)化,雖然該方法會(huì )導致大于萬(wàn)分之一的過(guò)濾遺 失率。 2.4 數據寫(xiě)入 選擇非關(guān)系性數據庫 MongoDB 作為硬碟數據庫與 scrapy 進(jìn)行搭配使用,在 pipeline 中對 item 數據進(jìn)行 MongoDB 的寫(xiě)入操作。 3 基本實(shí)現步驟 配置:Windows7 64-bit、Python:2.7.11、 Anaconda 4.0.0 (64-bit)、IDE:Pycharm 3.4.1、Scrapy:1.3.2Redis:X64-3.2、MongoDB:3.2.12 代碼實(shí)現須要對幾個(gè)文件進(jìn)行設置和編撰:items、settings、spiders、pipelines。
Items:這是一個(gè)爬取數據的基礎數據結構類(lèi),由其來(lái)儲存爬蟲(chóng)爬取的鍵值性數據,關(guān)鍵 的就是這條句子:_id = Field() _id 表示的生成一個(gè)數據對象,在 Items 中可以按照須要設定 多個(gè)數據對象。 Settings:ITEM_PIPELINES 該參數決定了 item 的處理方式;DOWNLOAD_DELAY 這個(gè) 是下載的間隔時(shí)間;SCHEDULER 指定作為總的任務(wù)協(xié)調器的類(lèi); SCHEDULER_QUEUE_CLASS 這個(gè)參數是設定處理 URL 的隊列的工作模式一共有四種,一般 選用 SpiderSimpleQueue 即可。 spiders:該文件就是爬蟲(chóng)主要功能的實(shí)現,首先設定該爬蟲(chóng)的基本信息:name、domain、 redis_key、start_urls。爬蟲(chóng)的第一步都是執行方式 start_requests,其中核心句子 yield Request (url,callback)用以按照 url 產(chǎn)生一個(gè) request 并且將 response 結果回傳給 callback 方法。 callback 的方式中通常借助 xpath 或者正則表達式對 response 中包含的 html 代碼進(jìn)行解析,產(chǎn) 生所須要的數據以及新的任務(wù) url。
pipelines:該文件作為數據處理、存儲的代碼段分布式爬蟲(chóng)框架,將在 items 數據被創(chuàng )建后被調用,其中 process_item 的方式就是被調用的方式,所以一定要將其重畫(huà),根據實(shí)際須要把數據借助方式 dict()轉化為字典數據,最后寫(xiě)入 MongoDB。 完成編撰后,在布署的時(shí)侯,start_url 的隊列只能是第一個(gè)運行的爬蟲(chóng)進(jìn)行初始化,后續 運行的爬蟲(chóng)只能是把新的 url 進(jìn)行寫(xiě)入不能對其進(jìn)行再度初始化,部署爬蟲(chóng)的步驟也很簡(jiǎn)單, 只須要把相關(guān)的代碼拷貝到目標筆記本上,讓后 cmd 命令步入 spiders 的文件夾,運行命令 scrapy crawl XXXX,其中 XXXX 就是爬蟲(chóng)的名子,就完成了爬蟲(chóng)的布署和運行了。 龍源期刊網(wǎng) 4 結語(yǔ) 爬蟲(chóng)的實(shí)現,除了基本的步驟和參數設置之外,需要開(kāi)發(fā)者按照實(shí)際網(wǎng)站以及數據情況, 針對性的對爬取的策略、數據的去重、數據篩選進(jìn)行處理,對于爬蟲(chóng)的性能進(jìn)行有效優(yōu)化,為 之后的數據剖析做好良好的數據打算。同時(shí),根據須要可以考慮時(shí)間的誘因加入到數據結構 中,這就要求爬蟲(chóng)還能通過(guò)數據的時(shí)間去進(jìn)行增量爬取。 參考文獻 [1]使用 redis 如何實(shí)現一個(gè)網(wǎng)絡(luò )分布式爬蟲(chóng)[OL].http: //www.oschina.net/code/snippet_209440_20495/. [2]scrapy_redis 的使用解讀[OL].http://www.cnblogs.com/kylinlin/p/5198233.html.http: //blog.csdn.net/u012150179/art
利用 scrapy 集成社區爬蟲(chóng)功能
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 320 次瀏覽 ? 2020-05-13 08:00
當前只爬取了用戶(hù)主頁(yè)上一些簡(jiǎn)單的信息,如果有需求請講到我們的
?。?br />
代碼放到了github上,源碼
如圖所示,在之前的構架上(),我降低了黑色實(shí)線(xiàn)框內的部份,包括:
scrapy是一個(gè)python爬蟲(chóng)框架,想要快速實(shí)現爬蟲(chóng)推薦使用這個(gè)。
可以參考如下資料自行學(xué)習:
官方文檔和官方事例
一個(gè)簡(jiǎn)單明了的入門(mén)博客,注意:博客中scrapy的安裝步驟可以簡(jiǎn)化,直接使用 pip install scrapy,安裝過(guò)程中可能會(huì )缺乏幾個(gè)lib,ubuntu使用 apt-get install libffi-dev libxml2-dev libxslt1-dev -y
mongo特別適宜儲存爬蟲(chóng)數據,支持異構數據。這意味著(zhù)你可以隨時(shí)改變爬蟲(chóng)策略抓取不同的數據,而不用害怕會(huì )和先前的數據沖突(使用sql就須要操蛋的更改表結構了)。
通過(guò)scrapy的pipline來(lái)集成mongo,非常便捷。
安裝mongo
apt-get install mongodb
pip install pymongo
在編撰爬蟲(chóng)的過(guò)程中須要使用xpath表達式來(lái)提取頁(yè)面數據,在chrome中可以使用XPath Helper來(lái)定位元素,非常便捷。使用方式:
打開(kāi)XPath Helper插件
鼠標點(diǎn)擊一下頁(yè)面,按住shift鍵,把鍵盤(pán)聯(lián)通到須要選定的元素上,插件會(huì )將該元素標記為紅色,并給出對應的xpath表達式,如下圖:
在爬蟲(chóng)程序中使用這個(gè)表達式selector.xpath(..../text()").extract()
編寫(xiě)好爬蟲(chóng)后,我門(mén)可以通過(guò)執行scrapy crawl spidername命令來(lái)運行爬蟲(chóng)程序,但這還不夠。
通常我們通過(guò)自動(dòng)或則定時(shí)任務(wù)(cron)來(lái)執行爬蟲(chóng)爬蟲(chóng)社區,而這兒我們須要通過(guò)web應用來(lái)觸發(fā)爬蟲(chóng)。即,當用戶(hù)更新綁定的社交帳號時(shí),去執行一次爬蟲(chóng)。來(lái)剖析一下:
爬蟲(chóng)執行過(guò)程中會(huì )阻塞當前進(jìn)程,為了不阻塞用戶(hù)懇求,必須通過(guò)異步的方法來(lái)運行爬蟲(chóng)。
可能有多個(gè)用戶(hù)同時(shí)更新資料,這就要求才能同時(shí)執行多個(gè)爬蟲(chóng),并且要保證系統不會(huì )超員。
可以擴充成分布式的爬蟲(chóng)。
鑒于項目當前的構架,準備使用celery來(lái)執行異步爬蟲(chóng)。但是遇到了兩個(gè)問(wèn)題:
scrapy框架下,需要在scrapy目錄下執行爬蟲(chóng),否則難以獲取到settings,這個(gè)用上去有點(diǎn)別扭,不過(guò)能夠解決。
celery中反復運行scrapy的爬蟲(chóng)會(huì )報錯:raise error.ReactorNotRestartable()。原因是scrapy用的twisted調度框架,不可以在進(jìn)程中重啟。
stackoverflow上有討論過(guò)這個(gè)問(wèn)題,嘗試了一下,搞不定,放棄這個(gè)方案。如果你有解決這個(gè)問(wèn)題的方式,期待分享:)
scrapy文檔中提及了可以使用scrapyd來(lái)布署,scrapyd是一個(gè)用于運行scrapy爬蟲(chóng)的webservice,使用者才能通過(guò)http請求來(lái)運行爬蟲(chóng)。
你只須要使用scrapyd-client將爬蟲(chóng)發(fā)布到scrapyd中,然后通過(guò)如下命令就可以運行爬蟲(chóng)程序。
$ curl http://localhost:6800/schedule.json -d project=myproject -d spider=spider2
{"status": "ok", "jobid": "26d1b1a6d6f111e0be5c001e648c57f8"}
這意味哪些:
爬蟲(chóng)應用和自己的web應用完全前饋,只有一個(gè)http插口。
由于使用http插口,爬蟲(chóng)可以放到任何還能被訪(fǎng)問(wèn)的主機上運行。一個(gè)簡(jiǎn)易的分布式爬蟲(chóng),不是嗎?
scrapyd使用sqlite隊列來(lái)保存爬蟲(chóng)任務(wù),實(shí)現異步執行。
scrapyd可以同時(shí)執行多個(gè)爬蟲(chóng),最大進(jìn)程數可配,防止系統過(guò)載。
歡迎使用我們的爬蟲(chóng)功能來(lái)搜集社交資料。
成為雨點(diǎn)兒網(wǎng)用戶(hù)爬蟲(chóng)社區,進(jìn)入用戶(hù)主頁(yè),點(diǎn)擊編輯按鍵
填寫(xiě)社交帳號,點(diǎn)擊更新按鍵
爬蟲(chóng)會(huì )在幾秒內完成工作,刷新個(gè)人主頁(yè)能夠看見(jiàn)你的社區資料了,你也可以把個(gè)人主頁(yè)鏈接附在電子簡(jiǎn)歷中喲:) 查看全部
社區活躍度或則貢獻越來(lái)越遭到注重,往往會(huì )作為獲得工作或則承接項目的加分項。為了便捷用戶(hù)展示自己的社區資料,中降低了一個(gè)社區爬蟲(chóng)功能。
當前只爬取了用戶(hù)主頁(yè)上一些簡(jiǎn)單的信息,如果有需求請講到我們的
?。?br />

代碼放到了github上,源碼
如圖所示,在之前的構架上(),我降低了黑色實(shí)線(xiàn)框內的部份,包括:

scrapy是一個(gè)python爬蟲(chóng)框架,想要快速實(shí)現爬蟲(chóng)推薦使用這個(gè)。
可以參考如下資料自行學(xué)習:
官方文檔和官方事例
一個(gè)簡(jiǎn)單明了的入門(mén)博客,注意:博客中scrapy的安裝步驟可以簡(jiǎn)化,直接使用 pip install scrapy,安裝過(guò)程中可能會(huì )缺乏幾個(gè)lib,ubuntu使用 apt-get install libffi-dev libxml2-dev libxslt1-dev -y
mongo特別適宜儲存爬蟲(chóng)數據,支持異構數據。這意味著(zhù)你可以隨時(shí)改變爬蟲(chóng)策略抓取不同的數據,而不用害怕會(huì )和先前的數據沖突(使用sql就須要操蛋的更改表結構了)。
通過(guò)scrapy的pipline來(lái)集成mongo,非常便捷。
安裝mongo
apt-get install mongodb
pip install pymongo
在編撰爬蟲(chóng)的過(guò)程中須要使用xpath表達式來(lái)提取頁(yè)面數據,在chrome中可以使用XPath Helper來(lái)定位元素,非常便捷。使用方式:
打開(kāi)XPath Helper插件
鼠標點(diǎn)擊一下頁(yè)面,按住shift鍵,把鍵盤(pán)聯(lián)通到須要選定的元素上,插件會(huì )將該元素標記為紅色,并給出對應的xpath表達式,如下圖:

在爬蟲(chóng)程序中使用這個(gè)表達式selector.xpath(..../text()").extract()
編寫(xiě)好爬蟲(chóng)后,我門(mén)可以通過(guò)執行scrapy crawl spidername命令來(lái)運行爬蟲(chóng)程序,但這還不夠。
通常我們通過(guò)自動(dòng)或則定時(shí)任務(wù)(cron)來(lái)執行爬蟲(chóng)爬蟲(chóng)社區,而這兒我們須要通過(guò)web應用來(lái)觸發(fā)爬蟲(chóng)。即,當用戶(hù)更新綁定的社交帳號時(shí),去執行一次爬蟲(chóng)。來(lái)剖析一下:
爬蟲(chóng)執行過(guò)程中會(huì )阻塞當前進(jìn)程,為了不阻塞用戶(hù)懇求,必須通過(guò)異步的方法來(lái)運行爬蟲(chóng)。
可能有多個(gè)用戶(hù)同時(shí)更新資料,這就要求才能同時(shí)執行多個(gè)爬蟲(chóng),并且要保證系統不會(huì )超員。
可以擴充成分布式的爬蟲(chóng)。
鑒于項目當前的構架,準備使用celery來(lái)執行異步爬蟲(chóng)。但是遇到了兩個(gè)問(wèn)題:
scrapy框架下,需要在scrapy目錄下執行爬蟲(chóng),否則難以獲取到settings,這個(gè)用上去有點(diǎn)別扭,不過(guò)能夠解決。
celery中反復運行scrapy的爬蟲(chóng)會(huì )報錯:raise error.ReactorNotRestartable()。原因是scrapy用的twisted調度框架,不可以在進(jìn)程中重啟。
stackoverflow上有討論過(guò)這個(gè)問(wèn)題,嘗試了一下,搞不定,放棄這個(gè)方案。如果你有解決這個(gè)問(wèn)題的方式,期待分享:)
scrapy文檔中提及了可以使用scrapyd來(lái)布署,scrapyd是一個(gè)用于運行scrapy爬蟲(chóng)的webservice,使用者才能通過(guò)http請求來(lái)運行爬蟲(chóng)。
你只須要使用scrapyd-client將爬蟲(chóng)發(fā)布到scrapyd中,然后通過(guò)如下命令就可以運行爬蟲(chóng)程序。
$ curl http://localhost:6800/schedule.json -d project=myproject -d spider=spider2
{"status": "ok", "jobid": "26d1b1a6d6f111e0be5c001e648c57f8"}
這意味哪些:
爬蟲(chóng)應用和自己的web應用完全前饋,只有一個(gè)http插口。
由于使用http插口,爬蟲(chóng)可以放到任何還能被訪(fǎng)問(wèn)的主機上運行。一個(gè)簡(jiǎn)易的分布式爬蟲(chóng),不是嗎?
scrapyd使用sqlite隊列來(lái)保存爬蟲(chóng)任務(wù),實(shí)現異步執行。
scrapyd可以同時(shí)執行多個(gè)爬蟲(chóng),最大進(jìn)程數可配,防止系統過(guò)載。
歡迎使用我們的爬蟲(chóng)功能來(lái)搜集社交資料。
成為雨點(diǎn)兒網(wǎng)用戶(hù)爬蟲(chóng)社區,進(jìn)入用戶(hù)主頁(yè),點(diǎn)擊編輯按鍵

填寫(xiě)社交帳號,點(diǎn)擊更新按鍵

爬蟲(chóng)會(huì )在幾秒內完成工作,刷新個(gè)人主頁(yè)能夠看見(jiàn)你的社區資料了,你也可以把個(gè)人主頁(yè)鏈接附在電子簡(jiǎn)歷中喲:)
[讀后筆記](méi) python網(wǎng)路爬蟲(chóng)實(shí)戰 (李松濤)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 343 次瀏覽 ? 2020-05-12 08:03
用了大約一個(gè)晚上的時(shí)間,就把這本書(shū)看完了。
前面4章是基礎的python知識,有基礎的朋友可以略過(guò)。
scrapy爬蟲(chóng)部份,用了實(shí)例給你們說(shuō)明scrapy的用法網(wǎng)絡(luò )爬蟲(chóng)實(shí)例,不過(guò)若果之前沒(méi)用過(guò)scrapy的話(huà),需要漸漸上機敲擊代碼。
其實(shí)書(shū)中的事例都是很簡(jiǎn)單的事例,基本沒(méi)哪些反爬的限制,書(shū)中一句話(huà)說(shuō)的十分贊成,用scrapy寫(xiě)爬蟲(chóng),就是做填空題,而用urllib2寫(xiě)爬蟲(chóng),就是習作題,可以自由發(fā)揮。
書(shū)中沒(méi)有用更為便捷的requests庫。 內容搜索用的最多的是beatifulsoup, 對于xpah或則lxml介紹的比較少。 因為scrapy自帶的response就是可以直接用xpath,更為便捷。
對于scrapy的中間和pipeline的使用了一個(gè)事例,也是比較簡(jiǎn)單的反例。
書(shū)中沒(méi)有對驗證碼,分布式等流行的反爬進(jìn)行講解,應該適宜爬蟲(chóng)入門(mén)的朋友去看吧。
書(shū)中一點(diǎn)挺好的就是代碼都十分規范,而且雖然是寫(xiě)習作的使用urllib2,也有意模仿scrapy的框架去寫(xiě), 需要抓取的數據 獨立一個(gè)類(lèi),類(lèi)似于scrapy的item,數據處理用的也是叫pipleline的方式。
這樣寫(xiě)的益處就是, 每個(gè)模塊的功能都一目了然,看完第一個(gè)反例的類(lèi)和函數定義,后面的事例都是大同小異,可以推動(dòng)讀者的閱讀速率,非常贊。(這一點(diǎn)之后自己要學(xué)習,增加代碼的可復用性)
很多頁(yè)面url如今早已過(guò)期了,再次運行作者的源碼會(huì )返回好多404的結果。
失效的項目:
金逸影城
天氣預報
獲取代理:
本書(shū)的一些錯誤的地方:
1. 獲取金逸影廳的spider中,所有關(guān)于movie的拼寫(xiě)都拼錯為moive了。這個(gè)屬于德語(yǔ)錯誤。
2. 在testProxy.py 代碼中網(wǎng)絡(luò )爬蟲(chóng)實(shí)例, 由于在同一個(gè)類(lèi)中,一直在形成線(xiàn)程,最后造成線(xiàn)程過(guò)多,不能再形成線(xiàn)程。程序會(huì )中途退出。
File "C:\Python27\lib\threading.py", line 736, in start<br />
_start_new_thread(self.__bootstrap, ())<br />
thread.error: can't start new thread
可以更改成獨立函數的方式,而不是類(lèi)函數。
待續。 查看全部

用了大約一個(gè)晚上的時(shí)間,就把這本書(shū)看完了。
前面4章是基礎的python知識,有基礎的朋友可以略過(guò)。
scrapy爬蟲(chóng)部份,用了實(shí)例給你們說(shuō)明scrapy的用法網(wǎng)絡(luò )爬蟲(chóng)實(shí)例,不過(guò)若果之前沒(méi)用過(guò)scrapy的話(huà),需要漸漸上機敲擊代碼。
其實(shí)書(shū)中的事例都是很簡(jiǎn)單的事例,基本沒(méi)哪些反爬的限制,書(shū)中一句話(huà)說(shuō)的十分贊成,用scrapy寫(xiě)爬蟲(chóng),就是做填空題,而用urllib2寫(xiě)爬蟲(chóng),就是習作題,可以自由發(fā)揮。
書(shū)中沒(méi)有用更為便捷的requests庫。 內容搜索用的最多的是beatifulsoup, 對于xpah或則lxml介紹的比較少。 因為scrapy自帶的response就是可以直接用xpath,更為便捷。
對于scrapy的中間和pipeline的使用了一個(gè)事例,也是比較簡(jiǎn)單的反例。
書(shū)中沒(méi)有對驗證碼,分布式等流行的反爬進(jìn)行講解,應該適宜爬蟲(chóng)入門(mén)的朋友去看吧。
書(shū)中一點(diǎn)挺好的就是代碼都十分規范,而且雖然是寫(xiě)習作的使用urllib2,也有意模仿scrapy的框架去寫(xiě), 需要抓取的數據 獨立一個(gè)類(lèi),類(lèi)似于scrapy的item,數據處理用的也是叫pipleline的方式。
這樣寫(xiě)的益處就是, 每個(gè)模塊的功能都一目了然,看完第一個(gè)反例的類(lèi)和函數定義,后面的事例都是大同小異,可以推動(dòng)讀者的閱讀速率,非常贊。(這一點(diǎn)之后自己要學(xué)習,增加代碼的可復用性)
很多頁(yè)面url如今早已過(guò)期了,再次運行作者的源碼會(huì )返回好多404的結果。
失效的項目:
金逸影城
天氣預報
獲取代理:
本書(shū)的一些錯誤的地方:
1. 獲取金逸影廳的spider中,所有關(guān)于movie的拼寫(xiě)都拼錯為moive了。這個(gè)屬于德語(yǔ)錯誤。
2. 在testProxy.py 代碼中網(wǎng)絡(luò )爬蟲(chóng)實(shí)例, 由于在同一個(gè)類(lèi)中,一直在形成線(xiàn)程,最后造成線(xiàn)程過(guò)多,不能再形成線(xiàn)程。程序會(huì )中途退出。
File "C:\Python27\lib\threading.py", line 736, in start<br />
_start_new_thread(self.__bootstrap, ())<br />
thread.error: can't start new thread
可以更改成獨立函數的方式,而不是類(lèi)函數。
待續。
【Scrapy】走進(jìn)成熟的爬蟲(chóng)框架
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 338 次瀏覽 ? 2020-05-10 08:02
今天簡(jiǎn)單說(shuō)說(shuō)Scrapy的安裝。
前幾天有小伙伴留言說(shuō)能不能介紹推薦一下爬蟲(chóng)框架,我給他推薦了Scrapy,本來(lái)想偷個(gè)懶,推薦他去看官方文檔,里面有一些demo代碼可供學(xué)習測試。結果收到回復說(shuō)文檔中演示用到的網(wǎng)站已經(jīng)難以訪(fǎng)問(wèn)了。所以只能自己來(lái)簡(jiǎn)單寫(xiě)一下了,也算是自己一個(gè)學(xué)習記錄。
Scrapy是哪些?
定義介紹我也不復制粘貼了。簡(jiǎn)單來(lái)說(shuō),Scrapy是一個(gè)中小型的爬蟲(chóng)框架,框架的意義就在于幫你預設好了好多可以用的東西,讓你可以從復雜的數據流和底層控制中抽離下來(lái),專(zhuān)心于頁(yè)面的解析即可完成中大項目爬蟲(chóng),甚至是分布式爬蟲(chóng)。
但是爬蟲(chóng)入門(mén)是不推薦直接從框架入手的,直接從框架入手會(huì )使你頭暈目眩,覺(jué)得哪里哪里都看不懂,有點(diǎn)類(lèi)似于還沒(méi)學(xué)會(huì )基礎的措詞造句就直接套用模板寫(xiě)成文章,自然是非常費力的。所以還是推薦你們有一定的手寫(xiě)爬蟲(chóng)基礎再深入了解框架。(當然還沒(méi)有入門(mén)爬蟲(chóng)的朋友…可以催更我的爬蟲(chóng)入門(mén)文章…)
那么首先是安裝。
Python的版本選擇之前提過(guò),推薦你們全面擁抱Python 3.x。
很久以前,大概是我剛入門(mén)學(xué)習Scrapy時(shí)爬蟲(chóng)框架,Scrapy還沒(méi)有支持Python 3.x,那時(shí)一部分爬蟲(chóng)工程師把Scrapy不支持Python 3.x作為不進(jìn)行遷移的理由。當然了,那時(shí)更具體的緣由是Scrapy所依賴(lài)的twisted和mitmproxy不支持Python 3.x。
現在我仍然推薦你們全面擁抱Python 3.x。
先安裝Python
這次我們以本地環(huán)境來(lái)進(jìn)行安裝(Windows+Anaconda),由于Python的跨平臺特點(diǎn)爬蟲(chóng)框架,我們本地寫(xiě)的代碼可以很容易遷移到別的筆記本或服務(wù)器使用。(當然了,從規范使用的角度上推薦你們使用單獨的env,或者直接使用docker或則vagrant,不過(guò)那就說(shuō)來(lái)話(huà)長(cháng)了…以后可以考慮單獨介紹)
按照慣例,我們直接使用 pip install scrapy 進(jìn)行安裝。
那么,你大幾率會(huì )碰到這樣的錯誤:
具體的錯誤緣由…缺少Microsoft Visual C++ 14.0…你也可以自己通過(guò)其他渠道解決,當然我們最推薦的做法是直接使用 conda install scrapy 命令(前提是你安裝了Anaconda而非普通Python)。
如果碰到寫(xiě)入權限錯誤,請用管理員模式運行cmd。
之后我們可以寫(xiě)一個(gè)太小的demo,依然是官方案例中的DMOZ,DMOZ網(wǎng)站是一個(gè)知名的開(kāi)放式分類(lèi)目錄(Open DirectoryProject),原版的DMOZ已于今年的3月17日停止了營(yíng)運,目前網(wǎng)站處于403狀態(tài)。但是網(wǎng)上大量過(guò)去的教程都是以DMOZ為案例的。我為你們找到了原DMOZ網(wǎng)站的靜態(tài)鏡像站,大家可以直接訪(fǎng)問(wèn)
大家根據官方文檔的步驟繼續做就可以了,后續的問(wèn)題不大。
?。ǎ?br /> 需要注意的就是工作目錄問(wèn)題。
啟動(dòng)Scrapy項目。
scrapy startproject tutorial
進(jìn)入目錄,我們可以看見(jiàn)手動(dòng)生成的一些文件,這些文件就是scrapy框架所須要的最基礎的組織結構。
scrapy.cfg: 項目的配置文件
tutorial/: 該項目的python模塊。之后您將在此加入代碼。
tutorial/items.py: 項目中的item文件.
tutorial/pipelines.py: 項目中的pipelines文件.
tutorial/settings.py: 項目的設置文件.
tutorial/spiders/: 放置spider代碼的目錄. 查看全部

今天簡(jiǎn)單說(shuō)說(shuō)Scrapy的安裝。
前幾天有小伙伴留言說(shuō)能不能介紹推薦一下爬蟲(chóng)框架,我給他推薦了Scrapy,本來(lái)想偷個(gè)懶,推薦他去看官方文檔,里面有一些demo代碼可供學(xué)習測試。結果收到回復說(shuō)文檔中演示用到的網(wǎng)站已經(jīng)難以訪(fǎng)問(wèn)了。所以只能自己來(lái)簡(jiǎn)單寫(xiě)一下了,也算是自己一個(gè)學(xué)習記錄。
Scrapy是哪些?
定義介紹我也不復制粘貼了。簡(jiǎn)單來(lái)說(shuō),Scrapy是一個(gè)中小型的爬蟲(chóng)框架,框架的意義就在于幫你預設好了好多可以用的東西,讓你可以從復雜的數據流和底層控制中抽離下來(lái),專(zhuān)心于頁(yè)面的解析即可完成中大項目爬蟲(chóng),甚至是分布式爬蟲(chóng)。
但是爬蟲(chóng)入門(mén)是不推薦直接從框架入手的,直接從框架入手會(huì )使你頭暈目眩,覺(jué)得哪里哪里都看不懂,有點(diǎn)類(lèi)似于還沒(méi)學(xué)會(huì )基礎的措詞造句就直接套用模板寫(xiě)成文章,自然是非常費力的。所以還是推薦你們有一定的手寫(xiě)爬蟲(chóng)基礎再深入了解框架。(當然還沒(méi)有入門(mén)爬蟲(chóng)的朋友…可以催更我的爬蟲(chóng)入門(mén)文章…)
那么首先是安裝。
Python的版本選擇之前提過(guò),推薦你們全面擁抱Python 3.x。
很久以前,大概是我剛入門(mén)學(xué)習Scrapy時(shí)爬蟲(chóng)框架,Scrapy還沒(méi)有支持Python 3.x,那時(shí)一部分爬蟲(chóng)工程師把Scrapy不支持Python 3.x作為不進(jìn)行遷移的理由。當然了,那時(shí)更具體的緣由是Scrapy所依賴(lài)的twisted和mitmproxy不支持Python 3.x。
現在我仍然推薦你們全面擁抱Python 3.x。
先安裝Python
這次我們以本地環(huán)境來(lái)進(jìn)行安裝(Windows+Anaconda),由于Python的跨平臺特點(diǎn)爬蟲(chóng)框架,我們本地寫(xiě)的代碼可以很容易遷移到別的筆記本或服務(wù)器使用。(當然了,從規范使用的角度上推薦你們使用單獨的env,或者直接使用docker或則vagrant,不過(guò)那就說(shuō)來(lái)話(huà)長(cháng)了…以后可以考慮單獨介紹)
按照慣例,我們直接使用 pip install scrapy 進(jìn)行安裝。
那么,你大幾率會(huì )碰到這樣的錯誤:

具體的錯誤緣由…缺少Microsoft Visual C++ 14.0…你也可以自己通過(guò)其他渠道解決,當然我們最推薦的做法是直接使用 conda install scrapy 命令(前提是你安裝了Anaconda而非普通Python)。
如果碰到寫(xiě)入權限錯誤,請用管理員模式運行cmd。

之后我們可以寫(xiě)一個(gè)太小的demo,依然是官方案例中的DMOZ,DMOZ網(wǎng)站是一個(gè)知名的開(kāi)放式分類(lèi)目錄(Open DirectoryProject),原版的DMOZ已于今年的3月17日停止了營(yíng)運,目前網(wǎng)站處于403狀態(tài)。但是網(wǎng)上大量過(guò)去的教程都是以DMOZ為案例的。我為你們找到了原DMOZ網(wǎng)站的靜態(tài)鏡像站,大家可以直接訪(fǎng)問(wèn)
大家根據官方文檔的步驟繼續做就可以了,后續的問(wèn)題不大。
?。ǎ?br /> 需要注意的就是工作目錄問(wèn)題。
啟動(dòng)Scrapy項目。
scrapy startproject tutorial

進(jìn)入目錄,我們可以看見(jiàn)手動(dòng)生成的一些文件,這些文件就是scrapy框架所須要的最基礎的組織結構。
scrapy.cfg: 項目的配置文件
tutorial/: 該項目的python模塊。之后您將在此加入代碼。
tutorial/items.py: 項目中的item文件.
tutorial/pipelines.py: 項目中的pipelines文件.
tutorial/settings.py: 項目的設置文件.
tutorial/spiders/: 放置spider代碼的目錄.
Scrapy爬蟲(chóng)框架:抓取天貓淘寶數據
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 422 次瀏覽 ? 2020-05-05 08:05
通過(guò)天貓的搜索,獲取搜索下來(lái)的每件商品的銷(xiāo)量、收藏數、價(jià)格。
所以,最終的目的是通過(guò)獲取兩個(gè)頁(yè)面的內容,一個(gè)是搜索結果,從上面找下來(lái)每一個(gè)商品的詳盡地址,然后第二個(gè)是商品詳盡內容,從上面獲取到銷(xiāo)量、價(jià)格等。
有了思路如今我們先下載搜索結果頁(yè)面,然后再下載頁(yè)面中每一項詳盡信息頁(yè)面。
def _parse_handler(self, response):
''' 下載頁(yè)面 """
self.driver.get(response.url)
pass
很簡(jiǎn)單,通過(guò)self.driver.get(response.url)就能使用selenium下載內容,如果直接使用response中的網(wǎng)頁(yè)內容是靜態(tài)的。
上面說(shuō)了怎樣下載內容,當我們下載好內容后,需要從上面去獲取我們想要的有用信息,這里就要用到選擇器,選擇器構造方法比較多,只介紹一種,這里看詳盡信息:
>>> body = '<html><body><span>good</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').extract()
[u'good']
這樣就通過(guò)xpath取下來(lái)了good這個(gè)詞組,更詳盡的xpath教程點(diǎn)擊這兒。
Selector 提供了好多形式出了xpath,還有css選擇器,正則表達式,中文教程看這個(gè),具體內容就不多說(shuō),只須要曉得這樣可以快速獲取我們須要的內容。
簡(jiǎn)單的介紹了如何獲取內容后,現在我們從第一個(gè)搜索結果中獲取我們想要的商品詳盡鏈接,通過(guò)查看網(wǎng)頁(yè)源代碼可以看見(jiàn),商品的鏈接在這里:
...
<p class="title">
<a class="J_ClickStat" data-nid="523242229702" href="//detail.tmall.com/item.htm?spm=a230r.1.14.46.Mnbjq5&id=523242229702&ns=1&abbucket=14" target="_blank" trace="msrp_auction" traceidx="5" trace-pid="" data-spm-anchor-id="a230r.1.14.46">WD/西部數據 WD30EZRZ臺式機3T電腦<span class="H">硬盤(pán)</span> 西數藍盤(pán)3TB 替綠盤(pán)</a>
</p>
...
使用之前的規則來(lái)獲取到a元素的href屬性就是須要的內容:
selector = Selector(text=self.driver.page_source) # 這里不要省略text因為省略后Selector使用的是另外一個(gè)構造函數,self.driver.page_source是這個(gè)網(wǎng)頁(yè)的html內容
selector.css(".title").css(".J_ClickStat").xpath("./@href").extract()
簡(jiǎn)單說(shuō)一下,這里通過(guò)css工具取了class叫title的p元素,然后又獲取了class是J_ClickStat的a元素,最后通過(guò)xpath規則獲取a元素的href中的內容。啰嗦一句css中若果是取id則應當是selector.css("#title"),這個(gè)和css中的選擇器是一致的。
同理,我們獲取到商品詳情后,以獲取銷(xiāo)量為例,查看源代碼:
<ul class="tm-ind-panel">
<li class="tm-ind-item tm-ind-sellCount" data-label="月銷(xiāo)量"><div class="tm-indcon"><span class="tm-label">月銷(xiāo)量</span><span class="tm-count">881</span></div></li>
<li class="tm-ind-item tm-ind-reviewCount canClick tm-line3" id="J_ItemRates"><div class="tm-indcon"><span class="tm-label">累計評價(jià)</span><span class="tm-count">4593</span></div></li>
<li class="tm-ind-item tm-ind-emPointCount" data-spm="1000988"><div class="tm-indcon"><a href="//vip.tmall.com/vip/index.htm" target="_blank"><span class="tm-label">送天貓積分</span><span class="tm-count">55</span></a></div></li>
</ul>
獲取月銷(xiāo)量:
selector.css(".tm-ind-sellCount").xpath("./div/span[@class='tm-count']/text()").extract_first()
獲取累計評價(jià):
selector.css(".tm-ind-reviewCount").xpath("./div[@class='tm-indcon']/span[@class='tm-count']/text()").extract_first()
最后把獲取下來(lái)的數據包裝成Item返回。淘寶或則淘寶她們的頁(yè)面內容不一樣,所以規則也不同,需要分開(kāi)去獲取想要的內容。
Item是scrapy中獲取下來(lái)的結果,后面可以處理這種結果。
Item通常是放在items.py中
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
>>> product = Product(name='Desktop PC', price=1000)
>>> print product
Product(name='Desktop PC', price=1000)
>>> product['name']
Desktop PC
>>> product.get('name')
Desktop PC
>>> product['price']
1000
>>> product['last_updated']
Traceback (most recent call last):
...
KeyError: 'last_updated'
>>> product.get('last_updated', 'not set')
not set
>>> product['lala'] # getting unknown field
Traceback (most recent call last):
...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product # is name field populated?
True
>>> 'last_updated' in product # is last_updated populated?
False
>>> 'last_updated' in product.fields # is last_updated a declared field?
True
>>> 'lala' in product.fields # is lala a declared field?
False
>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
...
KeyError: 'Product does not support field: lala'
這里只須要注意一個(gè)地方,不能通過(guò)product.name的方法獲取,也不能通過(guò)product.name = "name"的形式設置值。
當Item在Spider中被搜集以后,它將會(huì )被傳遞到Item Pipeline,一些組件會(huì )根據一定的次序執行對Item的處理。
每個(gè)item pipeline組件(有時(shí)稱(chēng)之為“Item Pipeline”)是實(shí)現了簡(jiǎn)單方式的Python類(lèi)。他們接收到Item并通過(guò)它執行一些行為,同時(shí)也決定此Item是否繼續通過(guò)pipeline,或是被遺棄而不再進(jìn)行處理。
以下是item pipeline的一些典型應用:
現在實(shí)現一個(gè)Item過(guò)濾器,我們把獲取下來(lái)若果是None的數據形參為0,如果Item對象是None則丟棄這條數據。
pipeline通常是放在pipelines.py中
def process_item(self, item, spider):
if item is not None:
if item["p_standard_price"] is None:
item["p_standard_price"] = item["p_shop_price"]
if item["p_shop_price"] is None:
item["p_shop_price"] = item["p_standard_price"]
item["p_collect_count"] = text_utils.to_int(item["p_collect_count"])
item["p_comment_count"] = text_utils.to_int(item["p_comment_count"])
item["p_month_sale_count"] = text_utils.to_int(item["p_month_sale_count"])
item["p_sale_count"] = text_utils.to_int(item["p_sale_count"])
item["p_standard_price"] = text_utils.to_string(item["p_standard_price"], "0")
item["p_shop_price"] = text_utils.to_string(item["p_shop_price"], "0")
item["p_pay_count"] = item["p_pay_count"] if item["p_pay_count"] is not "-" else "0"
return item
else:
raise DropItem("Item is None %s" % item)
最后須要在settings.py中添加這個(gè)pipeline
ITEM_PIPELINES = {
'TaoBao.pipelines.TTDataHandlerPipeline': 250,
'TaoBao.pipelines.MysqlPipeline': 300,
}
后面那種數字越小,則執行的次序越靠前,這里先過(guò)濾處理數據,獲取到正確的數據后,再執行TaoBao.pipelines.MysqlPipeline添加數據到數據庫。
完整的代碼:[不帶數據庫版本][ 數據庫版本]。
之前說(shuō)的方法都是直接通過(guò)命令scrapy crawl tts來(lái)啟動(dòng)。怎么用IDE的調試功能呢?很簡(jiǎn)單通過(guò)main函數啟動(dòng)爬蟲(chóng):
# 寫(xiě)到Spider里面
if __name__ == "__main__":
settings = get_project_settings()
process = CrawlerProcess(settings)
spider = TmallAndTaoBaoSpider
process.crawl(spider)
process.start()
在獲取數據的時(shí)侯,很多時(shí)侯會(huì )碰到網(wǎng)頁(yè)重定向的問(wèn)題,scrapy會(huì )返回302之后不會(huì )手動(dòng)重定向后繼續爬取新地址,在scrapy的設置中,可以通過(guò)配置來(lái)開(kāi)啟重定向,這樣雖然域名是重定向的scrapy也會(huì )手動(dòng)到最終的地址獲取內容。
解決方案:settings.py中添加REDIRECT_ENABLED = True
很多時(shí)侯爬蟲(chóng)都有自定義數據,比如之前寫(xiě)的是硬碟關(guān)鍵字,現在通過(guò)參數的方法如何傳遞呢?
解決方案:
大部分時(shí)侯,我們可以取到完整的網(wǎng)頁(yè)信息,如果網(wǎng)頁(yè)的ajax懇求太多,網(wǎng)速很慢的時(shí)侯,selenium并不知道什么時(shí)候ajax懇求完成,這個(gè)時(shí)侯假如通過(guò)self.driver.get(response.url)獲取頁(yè)面天貓反爬蟲(chóng),然后通過(guò)Selector取數據天貓反爬蟲(chóng),很可能還沒(méi)加載完成取不到數據。
解決方案:通過(guò)selenium提供的工具來(lái)延后獲取內容,直到獲取到數據,或者超時(shí)。 查看全部
有了前兩篇的基礎,接下來(lái)通過(guò)抓取天貓和淘寶的數據來(lái)詳盡說(shuō)明,如何通過(guò)Scrapy爬取想要的內容。完整的代碼:[不帶數據庫版本][ 數據庫版本]。
通過(guò)天貓的搜索,獲取搜索下來(lái)的每件商品的銷(xiāo)量、收藏數、價(jià)格。
所以,最終的目的是通過(guò)獲取兩個(gè)頁(yè)面的內容,一個(gè)是搜索結果,從上面找下來(lái)每一個(gè)商品的詳盡地址,然后第二個(gè)是商品詳盡內容,從上面獲取到銷(xiāo)量、價(jià)格等。
有了思路如今我們先下載搜索結果頁(yè)面,然后再下載頁(yè)面中每一項詳盡信息頁(yè)面。
def _parse_handler(self, response):
''' 下載頁(yè)面 """
self.driver.get(response.url)
pass
很簡(jiǎn)單,通過(guò)self.driver.get(response.url)就能使用selenium下載內容,如果直接使用response中的網(wǎng)頁(yè)內容是靜態(tài)的。
上面說(shuō)了怎樣下載內容,當我們下載好內容后,需要從上面去獲取我們想要的有用信息,這里就要用到選擇器,選擇器構造方法比較多,只介紹一種,這里看詳盡信息:
>>> body = '<html><body><span>good</span></body></html>'
>>> Selector(text=body).xpath('//span/text()').extract()
[u'good']
這樣就通過(guò)xpath取下來(lái)了good這個(gè)詞組,更詳盡的xpath教程點(diǎn)擊這兒。
Selector 提供了好多形式出了xpath,還有css選擇器,正則表達式,中文教程看這個(gè),具體內容就不多說(shuō),只須要曉得這樣可以快速獲取我們須要的內容。
簡(jiǎn)單的介紹了如何獲取內容后,現在我們從第一個(gè)搜索結果中獲取我們想要的商品詳盡鏈接,通過(guò)查看網(wǎng)頁(yè)源代碼可以看見(jiàn),商品的鏈接在這里:
...
<p class="title">
<a class="J_ClickStat" data-nid="523242229702" href="//detail.tmall.com/item.htm?spm=a230r.1.14.46.Mnbjq5&id=523242229702&ns=1&abbucket=14" target="_blank" trace="msrp_auction" traceidx="5" trace-pid="" data-spm-anchor-id="a230r.1.14.46">WD/西部數據 WD30EZRZ臺式機3T電腦<span class="H">硬盤(pán)</span> 西數藍盤(pán)3TB 替綠盤(pán)</a>
</p>
...
使用之前的規則來(lái)獲取到a元素的href屬性就是須要的內容:
selector = Selector(text=self.driver.page_source) # 這里不要省略text因為省略后Selector使用的是另外一個(gè)構造函數,self.driver.page_source是這個(gè)網(wǎng)頁(yè)的html內容
selector.css(".title").css(".J_ClickStat").xpath("./@href").extract()
簡(jiǎn)單說(shuō)一下,這里通過(guò)css工具取了class叫title的p元素,然后又獲取了class是J_ClickStat的a元素,最后通過(guò)xpath規則獲取a元素的href中的內容。啰嗦一句css中若果是取id則應當是selector.css("#title"),這個(gè)和css中的選擇器是一致的。
同理,我們獲取到商品詳情后,以獲取銷(xiāo)量為例,查看源代碼:
<ul class="tm-ind-panel">
<li class="tm-ind-item tm-ind-sellCount" data-label="月銷(xiāo)量"><div class="tm-indcon"><span class="tm-label">月銷(xiāo)量</span><span class="tm-count">881</span></div></li>
<li class="tm-ind-item tm-ind-reviewCount canClick tm-line3" id="J_ItemRates"><div class="tm-indcon"><span class="tm-label">累計評價(jià)</span><span class="tm-count">4593</span></div></li>
<li class="tm-ind-item tm-ind-emPointCount" data-spm="1000988"><div class="tm-indcon"><a href="//vip.tmall.com/vip/index.htm" target="_blank"><span class="tm-label">送天貓積分</span><span class="tm-count">55</span></a></div></li>
</ul>
獲取月銷(xiāo)量:
selector.css(".tm-ind-sellCount").xpath("./div/span[@class='tm-count']/text()").extract_first()
獲取累計評價(jià):
selector.css(".tm-ind-reviewCount").xpath("./div[@class='tm-indcon']/span[@class='tm-count']/text()").extract_first()
最后把獲取下來(lái)的數據包裝成Item返回。淘寶或則淘寶她們的頁(yè)面內容不一樣,所以規則也不同,需要分開(kāi)去獲取想要的內容。
Item是scrapy中獲取下來(lái)的結果,后面可以處理這種結果。
Item通常是放在items.py中
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
>>> product = Product(name='Desktop PC', price=1000)
>>> print product
Product(name='Desktop PC', price=1000)
>>> product['name']
Desktop PC
>>> product.get('name')
Desktop PC
>>> product['price']
1000
>>> product['last_updated']
Traceback (most recent call last):
...
KeyError: 'last_updated'
>>> product.get('last_updated', 'not set')
not set
>>> product['lala'] # getting unknown field
Traceback (most recent call last):
...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product # is name field populated?
True
>>> 'last_updated' in product # is last_updated populated?
False
>>> 'last_updated' in product.fields # is last_updated a declared field?
True
>>> 'lala' in product.fields # is lala a declared field?
False
>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
...
KeyError: 'Product does not support field: lala'
這里只須要注意一個(gè)地方,不能通過(guò)product.name的方法獲取,也不能通過(guò)product.name = "name"的形式設置值。
當Item在Spider中被搜集以后,它將會(huì )被傳遞到Item Pipeline,一些組件會(huì )根據一定的次序執行對Item的處理。
每個(gè)item pipeline組件(有時(shí)稱(chēng)之為“Item Pipeline”)是實(shí)現了簡(jiǎn)單方式的Python類(lèi)。他們接收到Item并通過(guò)它執行一些行為,同時(shí)也決定此Item是否繼續通過(guò)pipeline,或是被遺棄而不再進(jìn)行處理。
以下是item pipeline的一些典型應用:
現在實(shí)現一個(gè)Item過(guò)濾器,我們把獲取下來(lái)若果是None的數據形參為0,如果Item對象是None則丟棄這條數據。
pipeline通常是放在pipelines.py中
def process_item(self, item, spider):
if item is not None:
if item["p_standard_price"] is None:
item["p_standard_price"] = item["p_shop_price"]
if item["p_shop_price"] is None:
item["p_shop_price"] = item["p_standard_price"]
item["p_collect_count"] = text_utils.to_int(item["p_collect_count"])
item["p_comment_count"] = text_utils.to_int(item["p_comment_count"])
item["p_month_sale_count"] = text_utils.to_int(item["p_month_sale_count"])
item["p_sale_count"] = text_utils.to_int(item["p_sale_count"])
item["p_standard_price"] = text_utils.to_string(item["p_standard_price"], "0")
item["p_shop_price"] = text_utils.to_string(item["p_shop_price"], "0")
item["p_pay_count"] = item["p_pay_count"] if item["p_pay_count"] is not "-" else "0"
return item
else:
raise DropItem("Item is None %s" % item)
最后須要在settings.py中添加這個(gè)pipeline
ITEM_PIPELINES = {
'TaoBao.pipelines.TTDataHandlerPipeline': 250,
'TaoBao.pipelines.MysqlPipeline': 300,
}
后面那種數字越小,則執行的次序越靠前,這里先過(guò)濾處理數據,獲取到正確的數據后,再執行TaoBao.pipelines.MysqlPipeline添加數據到數據庫。
完整的代碼:[不帶數據庫版本][ 數據庫版本]。
之前說(shuō)的方法都是直接通過(guò)命令scrapy crawl tts來(lái)啟動(dòng)。怎么用IDE的調試功能呢?很簡(jiǎn)單通過(guò)main函數啟動(dòng)爬蟲(chóng):
# 寫(xiě)到Spider里面
if __name__ == "__main__":
settings = get_project_settings()
process = CrawlerProcess(settings)
spider = TmallAndTaoBaoSpider
process.crawl(spider)
process.start()
在獲取數據的時(shí)侯,很多時(shí)侯會(huì )碰到網(wǎng)頁(yè)重定向的問(wèn)題,scrapy會(huì )返回302之后不會(huì )手動(dòng)重定向后繼續爬取新地址,在scrapy的設置中,可以通過(guò)配置來(lái)開(kāi)啟重定向,這樣雖然域名是重定向的scrapy也會(huì )手動(dòng)到最終的地址獲取內容。
解決方案:settings.py中添加REDIRECT_ENABLED = True
很多時(shí)侯爬蟲(chóng)都有自定義數據,比如之前寫(xiě)的是硬碟關(guān)鍵字,現在通過(guò)參數的方法如何傳遞呢?
解決方案:
大部分時(shí)侯,我們可以取到完整的網(wǎng)頁(yè)信息,如果網(wǎng)頁(yè)的ajax懇求太多,網(wǎng)速很慢的時(shí)侯,selenium并不知道什么時(shí)候ajax懇求完成,這個(gè)時(shí)侯假如通過(guò)self.driver.get(response.url)獲取頁(yè)面天貓反爬蟲(chóng),然后通過(guò)Selector取數據天貓反爬蟲(chóng),很可能還沒(méi)加載完成取不到數據。
解決方案:通過(guò)selenium提供的工具來(lái)延后獲取內容,直到獲取到數據,或者超時(shí)。
網(wǎng)絡(luò )爬蟲(chóng):使用Scrapy框架編撰一個(gè)抓取書(shū)籍信息的爬蟲(chóng)服務(wù)
采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 285 次瀏覽 ? 2020-05-04 08:06
BeautifulSoup是一個(gè)十分流行的Python網(wǎng)路抓取庫,它提供了一個(gè)基于HTML結構的Python對象。
雖然簡(jiǎn)單易懂,又能非常好的處理HTML數據,
但是相比Scrapy而言網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),BeautifulSoup有一個(gè)最大的缺點(diǎn):慢。
Scrapy 是一個(gè)開(kāi)源的 Python 數據抓取框架,速度快,強大,而且使用簡(jiǎn)單。
來(lái)看一個(gè)官網(wǎng)主頁(yè)上的簡(jiǎn)單并完整的爬蟲(chóng):
雖然只有10行左右的代碼,但是它的確是一個(gè)完整的爬蟲(chóng)服務(wù):
Scrapy所有的懇求都是異步的:
安裝(Mac)
pip install scrapy
其他操作系統請參考完整安裝指導:
Spider類(lèi)想要抒發(fā)的是:如何抓取一個(gè)確定了的網(wǎng)站的數據。比如在start_urls里定義的去那個(gè)鏈接抓取,parse()方法中定義的要抓取什么樣的數據。
當一個(gè)Spider開(kāi)始執行的時(shí)侯,它首先從start_urls()中的第一個(gè)鏈接開(kāi)始發(fā)起懇求網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),然后在callback里處理返回的數據。
Item類(lèi)提供低格的數據,可以理解為數據Model類(lèi)。
Scrapy的Selector類(lèi)基于lxml庫,提供HTML或XML轉換功能。以response對象作為參數生成的Selector實(shí)例即可通過(guò)實(shí)例對象的xpath()方法獲取節點(diǎn)的數據。
接下來(lái)將上一個(gè)Beautiful Soup版的抓取書(shū)籍信息的事例( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總)改寫(xiě)成Scrapy版本。
scrapy startproject book_project
這行命令會(huì )創(chuàng )建一個(gè)名為book_project的項目。
即實(shí)體類(lèi),代碼如下:
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field()
isbn = scrapy.Field()
price = scrapy.Field()
設置這個(gè)Spider的名稱(chēng),允許爬取的域名和從那個(gè)鏈接開(kāi)始:
class BookInfoSpider(scrapy.Spider):
name = "bookinfo"
allowed_domains = ["allitebooks.com", "amazon.com"]
start_urls = [
"http://www.allitebooks.com/security/",
]
def parse(self, response):
# response.xpath('//a[contains(@title, "Last Page →")]/@href').re(r'(\d+)')[0]
num_pages = int(response.xpath('//a[contains(@title, "Last Page →")]/text()').extract_first())
base_url = "http://www.allitebooks.com/security/page/{0}/"
for page in range(1, num_pages):
yield scrapy.Request(base_url.format(page), dont_filter=True, callback=self.parse_page) 查看全部
上周學(xué)習了BeautifulSoup的基礎知識并用它完成了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總),
BeautifulSoup是一個(gè)十分流行的Python網(wǎng)路抓取庫,它提供了一個(gè)基于HTML結構的Python對象。
雖然簡(jiǎn)單易懂,又能非常好的處理HTML數據,
但是相比Scrapy而言網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),BeautifulSoup有一個(gè)最大的缺點(diǎn):慢。
Scrapy 是一個(gè)開(kāi)源的 Python 數據抓取框架,速度快,強大,而且使用簡(jiǎn)單。
來(lái)看一個(gè)官網(wǎng)主頁(yè)上的簡(jiǎn)單并完整的爬蟲(chóng):

雖然只有10行左右的代碼,但是它的確是一個(gè)完整的爬蟲(chóng)服務(wù):
Scrapy所有的懇求都是異步的:
安裝(Mac)
pip install scrapy
其他操作系統請參考完整安裝指導:
Spider類(lèi)想要抒發(fā)的是:如何抓取一個(gè)確定了的網(wǎng)站的數據。比如在start_urls里定義的去那個(gè)鏈接抓取,parse()方法中定義的要抓取什么樣的數據。
當一個(gè)Spider開(kāi)始執行的時(shí)侯,它首先從start_urls()中的第一個(gè)鏈接開(kāi)始發(fā)起懇求網(wǎng)絡(luò )爬蟲(chóng)程序書(shū),然后在callback里處理返回的數據。
Item類(lèi)提供低格的數據,可以理解為數據Model類(lèi)。
Scrapy的Selector類(lèi)基于lxml庫,提供HTML或XML轉換功能。以response對象作為參數生成的Selector實(shí)例即可通過(guò)實(shí)例對象的xpath()方法獲取節點(diǎn)的數據。
接下來(lái)將上一個(gè)Beautiful Soup版的抓取書(shū)籍信息的事例( 使用Beautiful Soup編撰一個(gè)爬蟲(chóng) 系列隨筆匯總)改寫(xiě)成Scrapy版本。
scrapy startproject book_project
這行命令會(huì )創(chuàng )建一個(gè)名為book_project的項目。
即實(shí)體類(lèi),代碼如下:
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field()
isbn = scrapy.Field()
price = scrapy.Field()
設置這個(gè)Spider的名稱(chēng),允許爬取的域名和從那個(gè)鏈接開(kāi)始:
class BookInfoSpider(scrapy.Spider):
name = "bookinfo"
allowed_domains = ["allitebooks.com", "amazon.com"]
start_urls = [
"http://www.allitebooks.com/security/",
]
def parse(self, response):
# response.xpath('//a[contains(@title, "Last Page →")]/@href').re(r'(\d+)')[0]
num_pages = int(response.xpath('//a[contains(@title, "Last Page →")]/text()').extract_first())
base_url = "http://www.allitebooks.com/security/page/{0}/"
for page in range(1, num_pages):
yield scrapy.Request(base_url.format(page), dont_filter=True, callback=self.parse_page)


