scrapy實例:爬新片場視頻
寫在前面
新片場地址
https://www.xinpianchang.com/channel/index/sort-like?from=navigator
1、新建項目
創建項目xpc:scrapy startproject xpc
在xpc項目根目錄下創建虛擬環境:virtualenv env
啓用虛擬環境:
cd env/Scripts/
activate.bat
在項目目錄xpc/env/Scripts下,創建文件1.txt,用來保存我們需要用到的包名
編輯1.txt內容如下:
scrapy
redis
requests
pymysql
安裝:pip install -r 1.txt
上面這一步,如果是在linux中,
創建文件:touch 1.txt
修改文件:vim 1.txt
創建爬蟲文件discovery(注意:這一步在xpc根目錄下進行)
scrapy genspider discovery xinpianchang.com
用pycharm打開項目
修改入口地址,我們要爬的是新片場的發現頁
2、設置prcharm一鍵啓動scrapy項目
先找到虛擬環境裏 scrapy安裝位置:where scrapy
複製地址,開始配置
運行試試
配置成功
3、爬取視頻詳情頁
通過檢查代碼發現,每個視頻都在 < ul class=“video-list” >這個標籤裏的 < li >標籤裏面
查看裏面的a標籤我們發現視頻並不是直接以一個鏈接形式存在的
3.1、斷點運行分析
我們查看事件也沒有發現有用的信息:
鼠標點擊事件、鼠標按下事件等目前只看到一些公用的函數
我們給點擊事件增加一個斷點運行試試
現在點一下第一個視頻
分析了會jq裏面的各個參數也並沒有發現有用的信息
3.2、鏈接分析
斷點運行分析沒有發現有用的信息,我們點進一個視頻,分析鏈接試試
我們發現鏈接裏面包含數字,我們把這串數字在"發現頁"搜索試試
選中Elements標籤,用鼠標隨便點html元素,然後按ctrl+f搜索
搜索結果顯示每個li裏面都有一串類似的數字
我們隨便複製其中一個數字,帶入鏈接裏訪問
所以這個網址每個視頻的鏈接是https://www.xinpianchang.com/a數字串?from=ArticleList
我們只需要抓取每個li裏面的數字串然後拼接,就能得到視頻鏈接
3.3、xpath提取
CTRL+SHIFT+X 開啓XPath Helper插件
提取數字串://@data-articleid
提取電影名://div[@class=“title-wrap”]/h3/text()
提取視頻鏈接://video[@id=‘xpc_video’]/@src
3.4、代碼
discovery.py
# -*- coding: utf-8 -*-
import scrapy
class DiscoverySpider(scrapy.Spider):
name = 'discovery'
allowed_domains = ['xinpianchang.com']
start_urls = ['https://www.xinpianchang.com/channel/index/sort-like?from=navigator']
def parse(self, response):
pid_list = response.xpath('//@data-articleid').extract()
url = "https://www.xinpianchang.com/a%s?from=ArticleList"
for pid in pid_list:
yield response.follow(url % pid, self.parse_post)
def parse_post(self, response):
post = {}
# 這裏get()和extract_first()一樣
post['title'] = response.xpath('//div[@class="title-wrap"]/h3/text()').get()
yield post
運行試試
4、爬取視頻
4.1、分析頁面
找到視頻地址
匹配地址://video[@id=“xpc_video”]/@src
寫代碼運行
我們發現所有的video都是None,那這個地址可能是js動態加載的
打開多個視頻詳情頁,分析視頻地址,我們發現地址請求源:
https://openapi-vtom.vmovier.com/v3/video/一串字符?expand=resource&usage=xpc_web
我們只需要找到這串字符串是從哪兒來的
找到對應的js
找到這串數字,我們發現它是直接寫在html裏,提取字符串
vid, = re.findall('vid:\"(\w+)\"\,',response.text)
video_url = 'https://openapi-vtom.vmovier.com/v3/video/%s?expand=resource&usage=xpc_web'
request = Request(video_url % vid, callback=self.parse_video)
request.meta['post'] = post
yield request
這個域名和首頁域名不一樣,我們把它加進去
def parse_video(self, response):
post = response.meta['post']
result = json.loads(response.text)
post['video'] = result['data']['resource']['default']['url']
yield post
所有代碼
# -*- coding: utf-8 -*-
import json
import re
import scrapy
from scrapy import Request
class DiscoverySpider(scrapy.Spider):
name = 'discovery'
allowed_domains = ['xinpianchang.com', 'openapi-vtom.vmovier.com']
start_urls = ['https://www.xinpianchang.com/channel/index/sort-like?from=navigator']
def parse(self, response):
pid_list = response.xpath('//@data-articleid').extract()
url = "https://www.xinpianchang.com/a%s?from=ArticleList"
for pid in pid_list:
yield response.follow(url % pid, self.parse_post)
def parse_post(self, response):
post = {}
# 這裏get()和extract_first()一樣
post['title'] = response.xpath('//div[@class="title-wrap"]/h3/text()').get()
categorys = response.xpath('//span[contains(@class,"cate")]//text()').extract()
post['category'] = ''.join([category.strip() for category in categorys])
post['created_at'] = response.xpath('//span[contains(@class,"update-time")]/i//text()').get()
post['play_counts'] = response.xpath('//i[contains(@class,"play-counts")]/@data-curplaycounts').get()
vid, = re.findall('vid: \"(\w+)\",', response.text)
video_url = 'https://openapi-vtom.vmovier.com/v3/video/%s?expand=resource&usage=xpc_web'
request = Request(video_url % vid, callback=self.parse_video)
request.meta['post'] = post
yield request
def parse_video(self, response):
post = response.meta['post']
result = json.loads(response.text)
post['video'] = result['data']['resource']['default']['url']
yield post