一文搞定Scrapy和Selenium整合使用
前言
scrapy和selenium的整合使用
先定個小目標實現(xiàn)萬物皆可爬!我們是用scrapy框架來快速爬取頁面上的數(shù)據(jù),它是自帶并發(fā)的,速度是可以的。但是一些ajax異步的請求我們不能這么爬取。我們要視同selenium來進行l(wèi)azy loading,也就是懶加載,渲染到頁面加載數(shù)據(jù)。
一、開始準備

1. 包管理和安裝chrome驅(qū)動
首先你要安裝以下包:
pip install scrapy pip install selenium == 3.0.0 pip install pymysql pip install bs4
selenium新版本有bug,用3.0的版本。
chrome驅(qū)動的exe執(zhí)行文件,放到你項目的根目錄即可。下載地址:驅(qū)動
2. 爬蟲項目的創(chuàng)建(舉個栗子)
創(chuàng)建項目
scrapy startproject cnki
您爬取的目標網(wǎng)站
scrapy genspider cnki https://www.cnki.net
運行爬蟲
# 運行不導(dǎo)出(一般在pipelines做導(dǎo)出操作) scrapy crawl cnki # 針對不同的選擇可以導(dǎo)出為xlsx、json等格式文件 scrapy crawl demo -o demo.csv
3. setting.py的配置
配置數(shù)據(jù)源,如下:
DB_HOST = 'localhost' DB_PORT = 3306 DB_USER = 'root' DB_PASSWORD ='123456' DB_DATABASE = 'spider'
防止打印log日志信息
LOG_LEVEL = 'WARNING'
配置USER_AGENT(瀏覽器控制臺找一個)
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
配置DEFAULT_REQUEST_HEADERS(瀏覽器控制臺找一個)
{
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}隨機延遲
DOWNLOAD_DELAY = 3 RANDOMIZE_DOWNLOAD_DELAY=True
中間件權(quán)重配置(這些中間件給他打開 并且按照項目實際需求配置權(quán)重,越小越先執(zhí)行)
SPIDER_MIDDLEWARES # 蜘蛛中間件 DOWNLOADER_MIDDLEWARES # 下載中間件 ITEM_PIPELINES # 管道
二、代碼演示
1. 主爬蟲程序
1.初始化selenium (如果您不需要selenium,可以忽略這個 )
def __init__(self, *args,**kwargs):
option = webdriver.ChromeOptions() # 實例化一個瀏覽器對象
option.add_argument('--headless') # 添加參數(shù),option可以是headless,--headless,-headless
self.driver = webdriver.Chrome(options=option) # 創(chuàng)建一個無頭瀏覽器
# self.driver = webdriver.Chrome() # 創(chuàng)建一個無頭瀏覽器
time.sleep(3)
super(CnkiSpider, self).__init__(*args, **kwargs)
dispatcher.connect(self.close_driver,signals.spider_closed)2.定義開始請求頁面
下面我只放了一個url,其實可以定義一組的然后進行遍歷(一般是分頁url使用)
還有cookie、代理也可以在這里配置,詳情請看進去看源碼(不過一般在中間件配置)
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
# 這里可以設(shè)置多個頁面,一般用于分頁的
url=url,
)3.關(guān)閉selenium(一定要關(guān)掉)
def close_driver(self):
print("爬蟲正在退出,執(zhí)行關(guān)閉瀏覽器哦")
time.sleep(2)
self.driver.quit()4.解析頁面
這里就不多說,八仙過海各顯神通
def parse(self,response: HtmlResponse):
sel = Selector(response)
dds = sel.css('.journal > .main-w1 > dl > dd')
for dd in dds:
title = dd.css('h6 > a::attr(title)').extract_first()
link = dd.css('h6 > a::attr(href)').extract_first()
link = response.urljoin(link)
author = dd.css('.baseinfo > span > #author::attr(title)').extract_first()
abstract = dd.css('.abstract::text').extract_first()
count = dd.css('.opts > .opts-count > li > em::text').extract_first()
count = int(count)
date = dd.css('.opts > .opts-count > .date::text').extract_first()
date = date.split(':')[1]
date = datetime.datetime.strptime(date,"%Y-%m-%d")
rc = Recommend()
rc['title'] = title
rc['link'] = link
rc['author'] = author
rc['abstract'] = abstract
rc['count'] = count
rc['date'] = date
yield rc這里要注意我們yield可以返回不僅是item,也可以是Request,進行頁面詳情的請求(套娃)
yield Request(
url=link, # 這是上面頁面上的鏈接,用來進一步請求
callback=self.parse_detail, # 這是回調(diào)函數(shù)
cb_kwargs={'item':rc} # 這是把上面的item傳遞下來
)2. 中間件的配置
1.針對selenium
沒有selenium請忽略
class SeleniumDownloaderMiddleware:
def process_request(self, request , spider):
if spider.name == 'cnki':
spider.driver.get(request.url)
time.sleep(2)
print(f"當前訪問{request.url}")
spider.driver.refresh()
time.sleep(3)
return HtmlResponse(url=spider.driver.current_url,body=spider.driver.page_source,encoding='utf-8')2.SpiderMiddleware保持默認配置即可
3.DownloaderMiddleware可以配置cookie和代理之類的。如:
# 我自定義的解析cookie方法
def get_cookie_dict():
cookie_str = 填上你的cookie
cookie_dict = {}
for item in cookie_str.split(';'):
key, value = item.split('=',maxsplit=1)
cookie_dict[key] = value
return cookie_dict
COOKIES_DICT = get_cookie_dict()# 這是DownloaderMiddleware這是自帶的方法哈
def process_request(self, request : Request, spider):
request.cookies = COOKIES_DICT
return None3. 定義item對象
用來接受爬蟲到的數(shù)據(jù)
class Recommend(scrapy.Item):
title = scrapy.Field()
author = scrapy.Field()
abstract = scrapy.Field()
link = scrapy.Field()
count = scrapy.Field()
date = scrapy.Field()4. 定義管道
實現(xiàn)對數(shù)據(jù)庫的導(dǎo)入(你也可以寫excel的)
class RecommendPipeline:
@classmethod
def from_crawler(cls, crawler: Crawler):
host = crawler.settings['DB_HOST']
port = crawler.settings['DB_PORT']
username = crawler.settings['DB_USER']
password = crawler.settings['DB_PASSWORD']
database = crawler.settings['DB_DATABASE']
return cls(host, port, username, password, database)
def __init__(self, host, port, username, password, database):
# 1、與數(shù)據(jù)庫建立連接
self.conn = pymysql.connect(host=host, port=port, user=username, password=password, database=database,
charset='utf8mb4')
# 2、創(chuàng)建游標
self.cursor = self.conn.cursor()
# 3、批處理需要的容器
self.data = []
def process_item(self, item, spider):
title = item.get('title', '')
author = item.get('author', '')
abstract = item.get('abstract', '')
link = item.get('link', '')
count = item.get('count', '')
date = item.get('date', '')
# 如果要實現(xiàn)批處理:
self.data.append((title,author,abstract,link,count,date))
# 如果存夠了10條就進數(shù)據(jù)庫
if len(self.data) == 10:
self._to_write_db()
# 然后再清空
self.data.clear()
return item
def close_spider(self, spider):
# 如果最后不滿足10條
if len(self.data) > 0:
self._to_write_db()
self.conn.close()
def _to_write_db(self):
# 作為一個實時的推薦,我希望將查到的數(shù)據(jù)作為一個temp
# 'delete from tb_recommend where 1 = 1' 刪除滿,并且主鍵自增不會從1開始
self.cursor.execute(
'truncate table tb_recommend'
)
self.cursor.executemany(
'insert into tb_recommend (title,author,abstract,link,count,date) values (%s, %s, %s, %s, %s, %s)',
self.data
)
self.conn.commit()
記得寫入setting.py,設(shè)置其權(quán)重。
*接下來您就可以按照這種方法‘愉’ ‘快’的進行爬蟲啦!!! *
總結(jié)
這是scrapy和selenium的具體整合使用,scrapy框架的內(nèi)容還有很多方法還沒用到,都有待開發(fā)。其次就是selenium的填充之類的操作還沒有使用,還需要去復(fù)習(xí)selenium的api。
相關(guān)文章
python pandas利用fillna方法實現(xiàn)部分自動填充功能
這篇文章主要介紹了python pandas通過fillna方法實現(xiàn)部分自動填充功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
利用Python批量識別電子賬單數(shù)據(jù)的方法
這篇文章主要介紹了利用Python批量識別電子賬單數(shù)據(jù)的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02
python區(qū)分不同數(shù)據(jù)類型的方法
這篇文章主要介紹了python區(qū)分不同數(shù)據(jù)類型的方法實例以及相關(guān)知識點,需要的朋友們學(xué)習(xí)下。2019-10-10
詳解pycharm2020.1.1專業(yè)版安裝指南(推薦)
這篇文章主要介紹了pycharm2020.1.1專業(yè)版安裝指南,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08

