本次寫一個爬取網易新聞的案例。因為redis能處理高并發,存儲數據也可以,故不用mysql。而且新聞網站容易更新很多,而mysql只能持久化存儲。
import scrapy
import re
import json
import redis # 用它來去除重復, 記錄訪問過的urlclass WangyiSpider(scrapy.Spider):name = "wangyi"allowed_domains = ["163.com"]start_urls = ["https://news.163.com/special/cm_guoji/?callback=data_callback"]code_re_obj = re.compile(r"data_callback\((?P<code>.*)\)", re.S) # 1conn = redis.Redis(host="127.0.0.1", port=6379, password="123456", db=4, decode_responses=True)def parse(self, resp, **kwargs):# 執行后續操作之前. 一定要先確認好. 你收到的東西對不對.# print(resp.text)# scrapy獲取json格式的數據. 可以直接resp.json(), 直接拿到字典# json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)# 典型的. 你拿到的數據不是json# print(resp.json())code = WangyiSpider.code_re_obj.search(resp.text).group("code")news = json.loads(code)for new in news:# print(new.get("tlink"))# print(new['tlink'])# print(new['title'])# 我要采集新聞的內容# 發請求. 獲取到詳情頁中的內容# 需要判斷該url是否已經被訪問過了.# 必須得知道我訪問過什么 需要把已經訪問過的東西記錄下來.tlink = new['tlink']if self.conn.sismember("news:wangyi", tlink):print("已經訪問過了. ")else:yield scrapy.Request(url=new['tlink'], callback=self.parse_detail)# 用url進行控制是否訪問過了 # 77777 9999# 如果是post請求呢?# http://www.baidu.com/a/b formdata: id=10086 => 樵夫11愛你# http://www.baidu.com/a/b formdata: id=10087 => 樵夫12愛你# http://www.baidu.com/a/b formdata: id=10088 => 樵夫2123愛你# http://www.baidu.com/a/b formdata: id=10089 => 樵夫12321愛你# 增量爬蟲. 但是這個增量爬蟲和樵夫講的不一樣了. 樵夫去重復用的是url. 每個詳情頁的url都是不一樣的# 增量爬蟲的核心邏輯是 去除重復.# data_callback([{title: "韓男子性侵)", ....}])# 這是典型的jsonp的邏輯# xxxxxx(數據)# 可以用正則表達式來完成數據的提取def parse_detail(self, resp):print(resp.url)post_body = resp.xpath("//div[@class='post_body']/p/text()").extract()post_title = resp.xpath("//h1[@class='post_title']/text()").extract_first()post_body = "".join(post_body).strip()print(post_title, post_body)# 16個庫.# news:# wangyi# tengxun# xxxxself.conn.sadd("news:wangyi", resp.url) #2
運行的講解一:開啟redis
這里的意思是,我們為了“驗證訪問的url”每次訪問都是不一樣的,如果訪問了,我們就不再訪問
但是如果是post請求,我們就可以如上圖那樣記錄“不一樣的參數”