最近這兩週在忙着給公司爬一點數據,更文的速度有一點降低,預計今天就爬完了,總結總結經驗。css
其實以前我司是有專門作爬蟲的,不用前端這邊出人幹活。後來那人離職了,有可能就沒有爬蟲這方面的需求了。忽然又有了一些,前端這邊出人作一下。老大說用 py
作,前期先調研一下。html
爬蟲其實原理上很簡單,咱們==客戶端,他們==服務端。
客戶端發送請求 req
,服務端返回響應 rsp
。拿到響應以後解析數據,入庫,就完事了。前端
通常來講請求分爲兩種,拉數據 get
比較多。
偶爾部分接口須要登陸,那就是多帶 cookie
或者 headers
。
其實還有一部分工做就是分析入參。vue
get
url
上post
body
裏返回數據大致上是兩種python
JSON
PC
和 M
端的進度不了,有可能都不是一個項目組,因此實現方式就會有差異。html
JSON
接口。無奈只能走解析 HTML
的路子。Node
以前給後臺搭架子的時候使用過,主要功能點以下:mysql
headers、cookie
)token
py
老大說要用這個東西。諮詢了一下其餘朋友,說可使用下面的工具。sql
requests
+ beautifulSoup
requests
發請求, beautifulSoup
解析 HTML
。比較原始。scrapy
ua
等功能。前端實現
我一個鐵頭娃,怎麼能輕言放棄?身爲一個前端er,仍是這些 api
讓我更加親切數據庫
XHR
cookie
啥的都自帶。無敵就是這麼寂寞。iframe
針對 HTML
類型的處理。同域的狀況下,也無敵好嗎?json
HTML
獲取 DOM
節點?window
上的對象。vue SSR 你感受到了威脅嗎?網上其餘服務商提供的接口(真香啊)。有免費的有收費的,通常免費的限量。網頁爬蟲
好了上面說了那麼多,建議老大限制,我選擇了 scrapy
。
scrapy
是一個網頁爬蟲框架,神馬叫作爬蟲,若是沒據說過,那就:內事不知問度娘,外事不決問谷歌,百度或谷歌一下吧!……(這裏的省略號表明scrapy
很牛逼,基本神馬都能爬,包括你喜歡的蒼老師……這裏就不翻譯了)
看到這個騷的飛起的介紹了嗎?沒錯,我就是在上面學的。scrapy 中文站。接下來我就介紹一下我認爲對於新手比較關注的東西
scrapy
處理器中的 response
標識你拿到的 rsp 上面自帶了一些方法,通常來講須要關注的只有兩個
quote.css('span.text::text').extract_first()
中的 'span.text::text'
眼熟嗎?
沒錯,就是咱們經常使用的選擇器。經過這個 api
,咱們能夠把咱們想要的數據,限時在一個很小的範圍,而後拿字符串便可。
啥?你說你不會 css
選擇器?前端培訓-初級階段(5 - 8)-CSS選擇器(基本、層級、屬性、僞類、僞狀態)
extract()
函數提取列表extract_first()
表明提取第一個元素。基本等價於 extract()[0]
::text
選擇其中的文字::attr(href)
提取屬性quote.xpath('span/small/text()').extract_first()
文檔,這個我不會,我也沒看
import json
使用這個類庫解析如:json.loads(response.body.decode('utf-8'))
import urllib
能夠用來給中文字符 encode
yield scrapy.FormRequest( url, method = 'GET', headers = self.headers, formdata={}, callback = self.parse_list, dont_filter = True, meta = { 'offset': 0, })
數據放入 formdata
傳遞便可。
yield scrapy.FormRequest( url, method = 'POST', headers = self.headers, formdata={}, callback = self.parse_list, dont_filter = True, meta = { 'offset': 0, })
meta = { 'offset': 0, }
以下方式接收
disstid = response.meta['offset']
scrapy crawl argsSpider -a tag=愛情
內部是使用以下命令能夠接收到。
def start_requests(self): url = 'http://lab.scrapyd.cn/' tag = getattr(self, 'tag', None) # 獲取tag值,也就是爬取時傳過來的參數
大數據那邊說爬回來的數據要入庫。
scrapyMysql/scrapyMysql/items.py
編寫對應入庫字段。
import scrapy class ScrapymysqlItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() tag = scrapy.Field() # 標籤字段 cont = scrapy.Field() # 名言內容 pass
scrapyMysql/scrapyMysql/spiders/inputMysql.py
寫爬蟲處理操做時,入庫
item = ScrapymysqlItem() # 實例化item類 for v in mingyan: # 循環獲取每一條名言裏面的:名言內容、做者、標籤 item['cont'] = v.css('.text::text').extract_first() # 提取名言 tags = v.css('.tags .tag::text').extract() # 提取標籤 item['tag'] = ','.join(tags) # 數組轉換爲字符串 yield item # 把取到的數據提交給pipline處理
編寫MySQL存儲插件:MySQLPipeline.py
import pymysql.cursors class MySQLPipeline(object): def __init__(self): # 鏈接數據庫 self.connect = pymysql.connect( host='127.0.0.1', # 數據庫地址 port=3306, # 數據庫端口 db='scrapyMysql', # 數據庫名 user='root', # 數據庫用戶名 passwd='root', # 數據庫密碼 charset='utf8', # 編碼方式 use_unicode=True) # 經過cursor執行增刪查改 self.cursor = self.connect.cursor() def process_item(self, item, spider): self.cursor.execute( """insert into mingyan(tag, cont) value (%s, %s)""", # 純屬python操做mysql知識,不熟悉請惡補 (item['tag'], # item裏面定義的字段和表字段對應 item['cont'],)) # 提交sql語句 self.connect.commit() return item # 必須實現返回
settings啓動MySQLPipline組件
ITEM_PIPELINES = { 'scrapyMysql.MySQLPipline.MySQLPipeline': 300, }
到如今,咱們已經完成了全部基礎知識的積累。遇到不會咱們去裏看?。
總結一下須要注意點的
mysql
庫和個人不合,我換了一個MySQLdb