使用scrapy和selenium結合 爬取淘寶資訊
阿新 • • 發佈:2018-12-11
首先,發現淘寶資訊是需要進行下拉載入資訊,否則商品資訊為空
因此,在middleware.py中設定:
class ScrapyseleniumspiderDownloaderMiddleware(object): # def __init__(self): # self.chrome_driver = Chrome() @classmethod def from_crawler(cls, crawler): # This method is used by Scrapy to create your spiders. s = cls() crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) return s def process_request(self, request, spider): if spider.name == 'taobao': # 返回Response物件,不在執行Download下載器及後續的中介軟體。 # 使用selenium開啟url,並請求。 spider.chrome_driver.get(request.url) # 模擬瀏覽器滾動,目的是將頁面中所有的電腦資訊載入完畢,然後再返回html原始碼。 for x in range(1, 11, 2): # 整個高度分5次滾動完畢,計算每次滾動的高度是多少。 height = float(x) / 10 js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % height spider.chrome_driver.execute_script(js) time.sleep(1) # 頁面滾動完畢,構造Response物件,並返回即可。 response = HtmlResponse(url=request.url, body=spider.chrome_driver.page_source, encoding='utf8', request=request) return response elif spider.name == 'weibo': # 返回None,將request物件交給後續的中介軟體處理。 return None elif spider.name == 'zhihu': return None
接著,在主爬蟲檔案taobao.py中進行寫程式碼
import scrapy from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions """ scrapy和selenium結合使用,爬取動態網站或者是訪問有IP限制(驗證碼)的網站。 scrapy也只能爬取靜態網站,必須結合js渲染引擎,才能載入js資料。 1- 能找到專門的json介面,最方便的方式; 2- 在網頁原始碼中,<script>標籤中,是否含有json字串,goods_list = {}; 3- 再原始碼中,通過xpath, css等進行標籤的提取; 4- 再通過selenium、pyspider進行資料提取; """ class TaobaoSpider(scrapy.Spider): name = 'taobao' allowed_domains = ['taobao.com'] start_urls = ['https://s.taobao.com/search?q=%E7%AC%94%E8%AE%B0%E6%9C%AC%E7%94%B5%E8%84%91&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20180919&ie=utf8'] def __init__(self): super(TaobaoSpider, self).__init__() option = ChromeOptions() # headless: 設定瀏覽器物件為無頭瀏覽器。無介面的瀏覽器驅動,可以節省瀏覽器渲染頁面的時間,缺點是除錯不方便。 # 除錯期間:使用有頭瀏覽器,通過介面檢視效果更佳直觀; # 執行期間:使用無頭瀏覽器,提高爬取效率; option.headless = True self.chrome_driver = Chrome(options=option) def parse(self, response): # 提取膝上型電腦的價格和名稱 divs = response.xpath('//div[@class="info-cont"]') print(len(divs)) for div in divs: # 獲取每一個電腦資訊所在的div標籤 # 在div的基礎上,再去定位價格、名稱 title = div.xpath('./div[@class="title-row "]/a/@title').extract_first('') price = div.css('.sale-row .price > strong::text').extract_first('') print(title, price) def closed(self, reason): # 爬蟲關閉時,會執行原始碼中的close()方法,而close()內部會呼叫這個closed()方法。 self.chrome_driver.close()