目的:把精彩豆列頻道里的每個豆列里的內容抓取出來。
流程是抓取目錄頁精彩豆列頻道豆列的地址-對每個豆列所有頁數都抓取具體內容、網址、時間。
這就很標準crawlspider干的活了,把目錄頁的地址寫成start_request依次爬取,然后對每個豆列都用rules控制。
圖片.png
圖片.png
目錄頁的分析:
豆瓣豆列挺有意思,沒做分頁,直接js獲取數據,json數據又長得像html的樣子,沒別的參數非常好爬。
json長這樣:
request
有了這兩項就可以想提取多少就提取多少豆列地址了,我做了前200個。
import scrapy
from scrapy.spiders import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor
from pyquery import PyQuery as pq
import requests
from douban.items import DoubanItem
import logging
class DbSpider(CrawlSpider):
name = 'db'
# allowed_domains = ['douban.com/doulist/']
rules = (Rule(
LinkExtractor(allow ='\?start'), callback = 'parse_detail', follow = True),)
# restrict_xpaths = ('//*[@id="content"]/div/div[1]/div[25]/a')
def start_requests(self):
url = 'https://www.douban.com/j/doulist/doulists?start=0&limit=200'
res = requests.get(url)
cont = pq(res.json()['html'])
for item in cont('.doulist-item').items():
logging.info(item('.title a').attr('href'))
yield scrapy.Request(item('.title a').attr('href'))
def parse_detail(self, response):
logging.info(response.url)
res = pq(response.body)
for item in res('.doulist-item .mod').items():
dbitem = DoubanItem()
dbitem['title'] = item('.title a').text()
dbitem['index_url'] = response.url
logging.info(item('.title a').text())
dbitem['url'] = item('.title a').attr('href')
dbitem['times'] = item('.time span').text()
yield dbitem
有幾個坑:
- restrict_xpaths = ('//*[@id="content"]/div/div[1]/div[25]/a')可以提取url,但是遇到很多頁中間有省略項比如1 2...9 10,他就只能提取1,2,9,10,想來也是3-8都沒有顯示出來怎么提取呢,這時候用allow網址提取就好了,網址https://www.douban.com/doulist/37669191/?start=25&sort=time&playable=0&sub_type=,相似性是‘start=’前面的問號需轉譯。
2.rules需iterable,這次rules只有一項所以要在后面加逗號。
3.restrict_xpaths用瀏覽器提取