<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Scrapy一個開源和共同作業的框架,其最初是為了頁面抓取 (更確切來說, 網路抓取 )所設計的,使用它可以以快速、簡單、可延伸的方式從網站中提取所需的資料。但目前Scrapy的用途十分廣泛,可用於如資料探勘、監測和自動化測試等領域,也可以應用在獲取API所返回的資料(例如 Amazon Associates Web Services ) 或者通用的網路爬蟲。
Scrapy 是基於twisted框架開發而來,twisted是一個流行的事件驅動的python網路框架。因此Scrapy使用了一種非阻塞(又名非同步)的程式碼來實現並行。整體架構大致如下
IO多路複用
# 引擎(EGINE)(大總管)
引擎負責控制系統所有元件之間的資料流,並在某些動作發生時觸發事件。有關詳細資訊,請參見上面的資料流部分。
# 排程器(SCHEDULER)
用來接受引擎發過來的請求, 壓入佇列中, 並在引擎再次請求的時候返回. 可以想像成一個URL的優先順序佇列, 由它來決定下一個要抓取的網址是什麼, 同時去除重複的網址
# 下載器(DOWLOADER)
用於下載網頁內容, 並將網頁內容返回給EGINE,下載器是建立在twisted這個高效的非同步模型上的
# 爬蟲(SPIDERS)
SPIDERS是開發人員自定義的類,用來解析responses,並且提取items,或者傳送新的請求
# 專案管道(ITEM PIPLINES)
在items被提取後負責處理它們,主要包括清理、驗證、持久化(比如存到資料庫)等操作
# 兩個中介軟體
-爬蟲中介軟體
-下載中介軟體(用的最多,加頭,加代理,加cookie,整合selenium)
# 1 框架 不是 模組 # 2 號稱爬蟲界的django(你會發現,跟django很多地方一樣) # 3 安裝 -mac,linux平臺:pip3 install scrapy -windows平臺:pip3 install scrapy(大部分人可以) - 如果失敗: 1、pip3 install wheel #安裝後,便支援通過wheel檔案安裝軟體,wheel檔案官網:https://www.lfd.uci.edu/~gohlke/pythonlibs 3、pip3 install lxml 4、pip3 install pyopenssl 5、下載並安裝pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/ 6、下載twisted的wheel檔案:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 7、執行pip3 install 下載目錄Twisted-17.9.0-cp36-cp36m-win_amd64.whl 8、pip3 install scrapy # 4 在script資料夾下會有scrapy.exe可執行檔案 -建立scrapy專案:scrapy startproject 專案名 (django建立專案) -建立爬蟲:scrapy genspider 爬蟲名 要爬取的網站地址 # 可以建立多個爬蟲 # 5 命令啟動爬蟲 -scrapy crawl 爬蟲名字 -scrapy crawl 爬蟲名字 --nolog # 沒有紀錄檔輸出啟動 # 6 檔案執行爬蟲(推薦使用) -在專案路徑下建立一個main.py,右鍵執行即可 from scrapy.cmdline import execute # execute(['scrapy','crawl','chouti','--nolog']) # 沒有設定紀錄檔級別 execute(['scrapy','crawl','chouti']) # 設定了紀錄檔級別
-crawl_chouti # 專案名 -crawl_chouti # 跟專案一個名,資料夾 -spiders # spiders:放著爬蟲 genspider生成的爬蟲,都放在這下面 -__init__.py -chouti.py # 抽屜爬蟲 -cnblogs.py # cnblogs 爬蟲 -items.py # 對比django中的models.py檔案 ,寫一個個的模型類 -middlewares.py # 中介軟體(爬蟲中介軟體,下載中介軟體),中介軟體寫在這 -pipelines.py # 寫持久化的地方(持久化到檔案,mysql,redis,mongodb) -settings.py # 組態檔 -scrapy.cfg # 不用關注,上線相關的 # 組態檔settings.py ROBOTSTXT_OBEY = False # 是否遵循爬蟲協定,強行執行 USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36' # 請求頭中的ua,去瀏覽器複製,或者用ua池拿 LOG_LEVEL='ERROR' # 這樣設定,程式錯誤資訊才會列印, #啟動爬蟲直接 scrapy crawl 爬蟲名 就沒有紀錄檔輸出 # scrapy crawl 爬蟲名 --nolog # 設定了就不需要這樣啟動了 # 爬蟲檔案 class ChoutiSpider(scrapy.Spider): name = 'chouti' # 爬蟲名字 allowed_domains = ['https://dig.chouti.com/'] # 允許爬取的域,想要多爬就註釋掉 start_urls = ['https://dig.chouti.com/'] # 起始爬取的位置,爬蟲一啟動,會先向它發請求 def parse(self, response): # 解析,請求回來,自動執行parser,在這個方法中做解析 print('---------------------------',response)
# 1 解析,可以使用bs4解析 from bs4 import BeautifulSoup soup=BeautifulSoup(response.text,'lxml') soup.find_all() # bs4解析 soup.select() # css解析 # 2 內建的解析器 response.css response.xpath # 內建解析 # 所有用css或者xpath選擇出來的都放在列表中 # 取第一個:extract_first() # 取出所有extract() # css選擇器取文字和屬性: # .link-title::text # 取文字,資料都在data中 # .link-title::attr(href) # 取屬性,資料都在data中 # xpath選擇器取文字和屬性 # .//a[contains(@class,"link-title")/text()] #.//a[contains(@class,"link-title")/@href] # 內建css選擇期,取所有 div_list = response.css('.link-con .link-item') for div in div_list: content = div.css('.link-title').extract() print(content)
# 方式一(不推薦) -1 parser解析函數,return 列表,列表套字典 # 命令 (支援:('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle') # 資料到aa.json檔案中 -2 scrapy crawl chouti -o aa.json # 程式碼: lis = [] for div in div_list: content = div.select('.link-title')[0].text lis.append({'title':content}) return lis # 方式二 pipline的方式(管道) -1 在items.py中建立模型類 -2 在爬蟲中chouti.py,引入,把解析的資料放到item物件中(要用中括號) -3 yield item物件 -4 組態檔設定管道 ITEM_PIPELINES = { # 數位表示優先順序(數位越小,優先順序越大) 'crawl_chouti.pipelines.CrawlChoutiPipeline': 300, 'crawl_chouti.pipelines.CrawlChoutiRedisPipeline': 301, } -5 pipline.py中寫持久化的類 spider_open # 方法,一開始就開啟檔案 process_item # 方法,寫入檔案 spider_close # 方法,關閉檔案
# choutiaa.py 爬蟲檔案 import scrapy from chouti.items import ChoutiItem # 匯入模型類 class ChoutiaaSpider(scrapy.Spider): name = 'choutiaa' # allowed_domains = ['https://dig.chouti.com/'] # 允許爬取的域 start_urls = ['https://dig.chouti.com//'] # 起始爬取位置 # 解析,請求回來,自動執行parse,在這個方法中解析 def parse(self, response): print('----------------',response) from bs4 import BeautifulSoup soup = BeautifulSoup(response.text,'lxml') div_list = soup.select('.link-con .link-item') for div in div_list: content = div.select('.link-title')[0].text href = div.select('.link-title')[0].attrs['href'] item = ChoutiItem() # 生成模型物件 item['content'] = content # 新增值 item['href'] = href yield item # 必須用yield # items.py 模型類檔案 import scrapy class ChoutiItem(scrapy.Item): content = scrapy.Field() href = scrapy.Field() # pipelines.py 資料持久化檔案 class ChoutiPipeline(object): def open_spider(self, spider): # 一開始就開啟檔案 self.f = open('a.txt', 'w', encoding='utf-8') def process_item(self, item, spider): # print(item) # 寫入檔案的操作 self.f.write(item['content']) self.f.write(item['href']) self.f.write('n') return item def close_spider(self, spider): # 寫入完畢,最後關閉檔案 self.f.close() # setting.py ITEM_PIPELINES = { # 數位表示優先順序,越小優先順序越高 'chouti.pipelines.ChoutiPipeline': 300, 'chouti.pipelines.ChoutiRedisPipeline': 301, }
# settings.ps ITEM_PIPELINES = { # 數位表示優先順序,越小優先順序越高 'chouti.pipelines.ChoutiPipeline': 300, 'chouti.pipelines.ChoutiRedisPipeline': 301, } # pipelines.py # 儲存到redis from redis import Redis class ChoutiRedisPipeline(object): def open_spider(self, spider): # 不寫引數就用預設設定 self.conn = Redis(password='123') # 一開始就拿到redis物件 def process_item(self, item, spider): print(item) import json s = json.dumps({'content': item['content'], 'href': item['href']}) self.conn.hset('choudi_article', item['id'], s) return item def close_spider(self, spoder): pass # self.conn.close() # chouti.py import scrapy from chouti.items import ChoutiItem # 匯入模型類 class ChoutiaaSpider(scrapy.Spider): name = 'choutiaa' # allowed_domains = ['https://dig.chouti.com/'] # 允許爬取的域 start_urls = ['https://dig.chouti.com//'] # 起始爬取位置 # 解析,請求回來,自動執行parse,在這個方法中解析 def parse(self, response): print('----------------',response) from bs4 import BeautifulSoup soup = BeautifulSoup(response.text,'lxml') div_list = soup.select('.link-con .link-item') for div in div_list: content = div.select('.link-title')[0].text href = div.select('.link-title')[0].attrs['href'] id = div.attrs['data-id'] item = ChoutiItem() # 生成模型物件 item['content'] = content # 新增值 item['href'] = href item['id'] = id yield item # 必須用yield
#一.下載並安裝mongodb pip install pymongo
#二、在settings中開啟PIPELINES並把資料庫相應設定寫入 ITEM_PIPELINES = { '<spider_name>.pipelines.ChoutiPipeline': 300, } MONGODB_HOST = '127.0.0.1' # 埠號,預設27017 MONGODB_PORT = 27017 # 設定資料庫名稱 MONGODB_DBNAME = 'Chouti' # 存放本資料的表名稱 MONGODB_DOCNAME = 'Chouti'
#三.修改pipelines檔案 import pymongo from scrapy.utils.project import get_project_settings settings = get_project_settings() class DouluodaluPipeline(object): def __init__(self): # 獲取setting主機名、埠號和資料庫名稱 host = settings['MONGODB_HOST'] port = settings['MONGODB_PORT'] dbname = settings['MONGODB_DBNAME'] # 建立資料庫連線 client = pymongo.MongoClient(host=host,port=port) # 指向指定資料庫 mdb = client[dbname] # 獲取資料庫裡面存放資料的表名 self.post = mdb[settings['MONGODB_DOCNAME']] def process_item(self, item, spider): data = dict(item) # 向指定的表裡新增資料 self.post.insert(data) return item
import pymysql.cursors class MySQLPipeline(object): def __init__(self): # 連線資料庫 self.connect = pymysql.connect( host='127.0.0.1', # 資料庫地址 port=3306, # 資料庫埠 db='scrapyMysql', # 資料庫名 user='root', # 資料庫使用者名稱 passwd='root', # 資料庫密碼 charset='utf8', # 編碼方式 use_unicode=True) # 通過cursor執行增刪查改 self.cursor = self.connect.cursor() def process_item(self, item, spider): self.cursor.execute( """insert into mingyan(tag, cont) value (%s, %s)""", # 純屬python操作mysql知識,不熟悉請惡補 (item['tag'], # item裡面定義的欄位和表欄位對應 item['cont'],)) # 提交sql語句 self.connect.commit() return item # 必須實現返回
from selenium import webdriver from selenium.webdriver import ActionChains import time bro=webdriver.Chrome(executable_path='./chromedriver') bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') bro.implicitly_wait(10) #切換frame(很少) bro.switch_to.frame('iframeResult') div=bro.find_element_by_xpath('//*[@id="draggable"]') # 1 生成一個動作練物件 action=ActionChains(bro) # 2 點選並夯住某個控制元件 action.click_and_hold(div) # 3 移動(三種方式) # action.move_by_offset() # 通過座標(x,y) # action.move_to_element() # 到另一個標籤 # action.move_to_element_with_offset() # 到另一個標籤,再偏移一部分 for i in range(5): action.move_by_offset(10,10) # 4 真正的移動 action.perform() # 5 釋放控制元件(鬆開滑鼠) action.release() async def login(): for res in setting.user: try: username = res[0] password = res[1] # headless引數設為False,則變成有頭模式 browser = await launch( {'headless': False} ) # 開啟一個頁面 page = await browser.newPage() await page.setViewport(viewport={'width': 1280, 'height': 800}) res = await page.goto('https://login.taobao.com/', options={'timeout': 10000}) await page.type('#fm-login-id', username) await page.type('#fm-login-password', password) await page.waitFor(1000) # 等待時間 slider = await page.querySelector('#nc_1_n1z') # 是否有滾軸 if slider: try: print('有滾軸') await page.hover('#nc_1_n1z') # 不同場景的驗證碼模組能名字不同。 await page.mouse.down() await page.mouse.move(2000, 0, {'delay': random.randint(1000, 2000)}) await page.mouse.up() except Exception as e: print(e) input('驗證失敗,人工登入:') else: print('沒有滾軸') await page.click("#login-form > div.fm-btn > button") # 點選登入 input('進入登入成功頁面後,按回車:') return page except Exception as e: continue
- 在組態檔中進行相關的設定即可:(預設還有一套setting) #1 增加並行: 預設scrapy開啟的並行執行緒為32個,可以適當進行增加。在settings組態檔中修改CONCURRENT_REQUESTS = 100值為100,並行設定成了為100。 #2 提高紀錄檔級別: 在執行scrapy時,會有大量紀錄檔資訊的輸出,為了減少CPU的使用率。可以設定log輸出資訊為INFO或者ERROR即可。在組態檔中編寫:LOG_LEVEL = ‘INFO' # 3 禁止cookie: 如果不是真的需要cookie,則在scrapy爬取資料時可以禁止cookie從而減少CPU的使用率,提升爬取效率。在組態檔中編寫:COOKIES_ENABLED = False # 4禁止重試: 對失敗的HTTP進行重新請求(重試)會減慢爬取速度,因此可以禁止重試。在組態檔中編寫:RETRY_ENABLED = False # 5 減少下載超時: 如果對一個非常慢的連結進行爬取,減少下載超時可以能讓卡住的連結快速被放棄,從而提升效率。在組態檔中進行編寫:DOWNLOAD_TIMEOUT = 10 超時時間為10s
# pip3 install fake-useragent from fake_useragent import UserAgent ua = UserAgent(verify_ssl=False) print(ua.random) # 隨機獲取一個UserAgent
#大中介軟體:下載中介軟體,爬蟲中介軟體 # 1 寫在middlewares.py中(名字隨便命名) # 2 設定生效() # 爬蟲中介軟體 SPIDER_MIDDLEWARES = { 'cnblogs_crawl.middlewares.CnblogsCrawlSpiderMiddleware': 543, } # 下載中介軟體 DOWNLOADER_MIDDLEWARES = { 'cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware': 543, } # 下載中介軟體 # 在cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware中有五個方法 # 請求出去的時候 def process_request(self, request, spider) # Must either: # - return None: # 返回none繼續處理,進入下一個中介軟體 # - return Response: 當次請求結束,把Response丟給引擎處理(可以自己爬,包裝成Response) # - return Request : 相當於把Request重新給了引擎,引擎再去做排程 # - 拋異常:執行process_exception # 請求回來的時候 def process_response(self, request, response, spider) # - return a Response object :繼續處理當次Response,繼續走後續的中介軟體 # - return a Request object:重新給引擎做排程 # - 拋異常:執行process_exception # 請求異常的時候 def process_exception(self, request, exception, spider) # - return None: 不處理異常,繼續丟給下面 # - return a Response:停止例外處理,不丟給下面。給引擎。Response給爬蟲分析資料 # - return a Request:停止例外處理,不丟給下面。給引擎。Request重新排程
class CnblogsSpider(scrapy.Spider): name = 'cnblogs4' allowed_domains = ['www.cnblogs.com'] start_urls = ['http://wwwsadasd.cnblogs.com/'] # 錯誤的網址,報錯走例外處理 # 走例外處理,重新返回一個正確的Request物件 def process_exception(self, request, exception, spider): print(request.url) # http://wwwsadasd.cnblogs.com/ from scrapy.http import Request return Request('http://www.cnblogs.com/',callback=spider.parser_detail)
def process_request(self, request, spider): # 1 加cookie(request.cookies就是存取該網站的cookie) print(request.cookies) request.cookies={'name':"jeff",'age':18} # 從你的cookie池中取出來的, 字典 print(request.cookies) # 2 加代理 request.meta['proxy']=self.get_proxy() # 從代理池中獲取一個 print(request.meta['proxy']) # 3 修改ua from fake_useragent import UserAgent # ua模組,隨機獲取一個 ua = UserAgent(verify_ssl=False) request.headers['User-Agent']=ua.random print(request.headers) # 代理池 def get_proxy(self): import requests ret=requests.get('http://0.0.0.0:5010/get').json()['proxy'] print(ret) return ret return None
#可在兩個地方整合。 #1.process_request(請求出去的時候) # 推薦寫這裡,少請求一次。直接整合封裝 #2.process_response(請求回來的時候) # 不推薦,因為奪走了一次請求,回來再整合封裝 # 方案一:缺點很大。每次一請求都要開啟一個bro瀏覽器 def process_request(self, request, spider): from selenium import webdriver from scrapy.http import HtmlResponse bro = webdriver.Chrome(executable_path='../chromedriver') bro.get(request.url) text = bro.page_source response = HtmlResponse(url=request.url, body=text.encode('utf-8'), status=200) return response # 方案二:改進為一開始就開啟一個bro瀏覽器,後面都用這一個bro class CnblogsSpider(scrapy.Spider): name = 'cnblogs' from selenium import webdriver # 在爬蟲一開始就開啟bro物件 bro = webdriver.Chrome(executable_path='../chromedriver') # 在爬蟲中新新增的方法:關閉bro def close(spider, reason): spider.bro.close() # 爬蟲結束關閉 # 中介軟體中 def process_request(self, request, spider): from scrapy.http import HtmlResponse spider.bro.get(request.url) # 每個請求使用一個bro text = spider.bro.page_source response = HtmlResponse(url=request.url, body=text.encode('utf-8'), status=200) return response
什麼是增量爬取?
-增量爬取(100連結,150個連結)
-你寫的去重方案,佔得記憶體空間更小
-bitmap方案
-BloomFilter布隆過濾器
# 一、網址指紋 from scrapy.http import Request from scrapy.utils.request import request_fingerprint # 這種網址是一個 request1 = Request(url='https://www.baidu.com/s?name=jeff&age=18') request2 = Request(url='https://www.baidu.com/s?age=18&name=jeff') ret1=request_fingerprint(requests1) ret2=request_fingerprint(requests2) print(ret1) # 6961985868392ae44c15ada494ddeda856cf75fc print(ret2) # 6961985868392ae44c15ada494ddeda856cf75fc
# 安裝 # 1.需要先安裝bitarray #下載地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/ # 2.下載好之後 pip3 install 檔案拖進去 # 3.pip3 install pybloom_live #ScalableBloomFilter 可以自動擴容 from pybloom_live import ScalableBloomFilter bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.001, mode=ScalableBloomFilter.LARGE_SET_GROWTH) url = "https://www.baidu.com/s?name=jeff&age=18" url2 = "https://www.baidu.com/s?age=18&name=jeff" bloom.add(url) print(url in bloom) print(url2 in bloom)
使用一:新增網址(不推薦)
#BloomFilter 是定長的 from pybloom_live import BloomFilter bf = BloomFilter(capacity=1000) url='www.baidu.com' bf.add(url) print(url in bf) print("www.liuqingzheng.top" in bf)
使用二:新增網址指紋(推薦),配合指紋使用
from scrapy.http import Request from scrapy.utils.request import request_fingerprint from pybloom_live import BloomFilter request1 = Request(url='https://www.baidu.com/s?name=jeff&age=18') request2 = Request(url='https://www.baidu.com/s?age=18&name=jeff') ret1=request_fingerprint(request1) ret2=request_fingerprint(request2) print(ret1) # 6961985868392ae44c15ada494ddeda856cf75fc print(ret2) # 6961985868392ae44c15ada494ddeda856cf75fc bf = BloomFilter(capacity=1000) # 1000容量 bf.add(ret2) if ret1 in bf: print('已經爬過此網站,True') else: bf.add(ret1) # 新增 print('還沒有爬過此網站,返回false')
github地址:https://github.com/rmax/scrapy-redis # 1 安裝pip3 install scrapy-redis # 原始碼部分,不到1000行, # 1 原來的爬蟲繼承 from scrapy_redis.spiders import RedisSpider class CnblogsSpider(RedisSpider): #start_urls = ['http://www.cnblogs.com/'] redis_key = 'myspider:start_urls' # 起始地址為空,在redis中拿 # 2 在setting中設定 SCHEDULER = "scrapy_redis.scheduler.Scheduler" DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" ITEM_PIPELINES = { 'chouti.pipelines.Pipeline': 300, # 用自己的入庫類,比如mysql中 # 'scrapy_redis.pipelines.RedisPipeline': 300 # 存在別人寫好的redis入庫類 } REDIS_PARAMS = {'password':'123'} # 如果redis有密碼就設定 #其他更多設定見github # 3 多臺機器上啟動scrapy # 4 向reids中傳送起始url redis-cli lpush myspider:start_urls https://www.cnblogs.com
可以同時啟動兩個爬蟲,爬不同的網站。但是建議爬不同的網站新建專案
chouti.py 爬蟲:
import scrapy from chouti.items import ChoutiItem # 匯入模型類 class ChoutiaaSpider(scrapy.Spider): name = 'choutiaa' # allowed_domains = ['https://dig.chouti.com/'] # 允許爬取的域 start_urls = ['https://dig.chouti.com//'] # 起始爬取位置 # 解析,請求回來,自動執行parse,在這個方法中解析 def parse(self, response): print('----------------',response) from bs4 import BeautifulSoup soup = BeautifulSoup(response.text,'lxml') div_list = soup.select('.link-con .link-item') for div in div_list: content = div.select('.link-title')[0].text href = div.select('.link-title')[0].attrs['href'] id = div.attrs['data-id'] item = ChoutiItem() # 生成模型物件 item['content'] = content # 新增值 item['href'] = href item['id'] = id yield item # 必須用yield
cnblogs.py 爬蟲:
# -*- coding: utf-8 -*- import scrapy from bs4 import BeautifulSoup from chouti.items import CnblogsItem # 匯入模型類 from scrapy.http import Request class CnblogsSpider(scrapy.Spider): name = 'cnblogs' start_urls = ['https://www.cnblogs.com/'] def parse(self, response): print('------', response) soup = BeautifulSoup(response.text, 'lxml') div_list = soup.select('#post_list .post_item') for div in div_list: author = div.select('.post_item_foot a')[0].text content_url = div.select('h3 a')[0].attrs['href'] title = div.select('h3')[0].text content_summary = div.select('p')[0].text item = CnblogsItem() item['author'] = author item['content_url'] = content_url item['title'] = title item['content_summary'] = content_summary # print(f''' # 作者:{author} # 文章地址:{content_url} # 標題:{title} # 文章內容:{content_summary} # ''') # 繼續往深一層爬取,傳遞給content_parse yield Request(content_url, callback=self.content_parse, meta={'item': item}) # 獲取下一頁的標籤網址 next = soup.select('#paging_block > div > a:nth-last-child(1)')[0].attrs['href'] next = 'https://www.cnblogs.com/'+next yield Request(next) # 繼續爬取下一頁 def content_parse(self, response): item = response.meta.get('item') content = response.css('#cnblogs_post_body').extract_first() if not content: content = response.css('content').extract_first() item['content'] = content # print(item) yield item
items.py 模型類:
# -*- coding: utf-8 -*- # Define here the models for your scraped items # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class ChoutiItem(scrapy.Item): content = scrapy.Field() href = scrapy.Field() id = scrapy.Field() class CnblogsItem(scrapy.Item): author = scrapy.Field() content_url = scrapy.Field() title = scrapy.Field() content_summary = scrapy.Field() content = scrapy.Field()
pipelines.py 資料持久化檔案
# -*- coding: utf-8 -*- # Define your item pipelines here # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html # 儲存到檔案 class Pipeline(object): def open_spider(self, spider): # choutiaa爬蟲入庫前 if spider.name == 'choutiaa': # 一開始就開啟檔案 self.f = open('a.txt', 'w', encoding='utf-8') # cnblog爬蟲入庫前 elif spider.name == 'cnblogs': import pymysql self.conn = pymysql.Connect(host='127.0.0.1', port=3306, db='cnblogs', user='root', password="123",autocommit=True) def process_item(self, item, spider): # choutiaa爬蟲入庫中 if spider.name == 'choutiaa': # 寫入檔案的操作 self.f.write(item['content']) self.f.write(item['href']) self.f.write(item['id']) self.f.write('n') return item # cnblog爬蟲入庫中 elif spider.name == 'cnblogs': print('cnblogs入庫中') curser = self.conn.cursor() sql = 'insert into article (author,content_url,title,content_summary,content) values (%s,%s,%s,%s,%s)' curser.execute(sql, ( item['author'], item['content_url'], item['title'], item['content_summary'], item['content'])) def close_spider(self, spider): # choutiaa爬蟲入庫結束 if spider.name == 'choutiaa': # 寫入完畢,最後關閉檔案 self.f.close() # cnblog爬蟲入庫結束 elif spider.name == 'cnblogs': print('cnblogs入庫完畢') self.conn.close()
main.py
from scrapy.cmdline import execute # execute(['scrapy','crawl','choutiaa']) execute(['scrapy','crawl','cnblogs'])
以上就是scarpy爬蟲框架整合selenium及詳細講解的詳細內容,更多關於scarpy爬蟲框架結構整合selenium的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45