欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一步步教你用python的scrapy編寫一個(gè)爬蟲

 更新時(shí)間:2019年04月17日 10:32:21   作者:fallinjava  
這篇文章主要給大家介紹了如何利用python的scrapy編寫一個(gè)爬蟲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用scrapy具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

介紹

本文將介紹我是如何在python爬蟲里面一步一步踩坑,然后慢慢走出來的,期間碰到的所有問題我都會(huì)詳細(xì)說明,讓大家以后碰到這些問題時(shí)能夠快速確定問題的來源,后面的代碼只是貼出了核心代碼,更詳細(xì)的代碼暫時(shí)沒有貼出來。

流程一覽

首先我是想爬某個(gè)網(wǎng)站上面的所有文章內(nèi)容,但是由于之前沒有做過爬蟲(也不知道到底那個(gè)語(yǔ)言最方便),所以這里想到了是用python來做一個(gè)爬蟲(畢竟人家的名字都帶有爬蟲的含義😄),我這邊是打算先將所有從網(wǎng)站上爬下來的數(shù)據(jù)放到ElasticSearch里面, 選擇ElasticSearch的原因是速度快,里面分詞插件,倒排索引,需要數(shù)據(jù)的時(shí)候查詢效率會(huì)非常好(畢竟爬的東西比較多😄),然后我會(huì)將所有的數(shù)據(jù)在ElasticSearch的老婆kibana里面將數(shù)據(jù)進(jìn)行可視化出來,并且分析這些文章內(nèi)容,可以先看一下預(yù)期可視化的效果(上圖了),這個(gè)效果圖是kibana6.4系統(tǒng)給予的幫助效果圖(就是說你可以弄成這樣,我也想弄成這樣😁)。后面我會(huì)發(fā)一個(gè)dockerfile上來(現(xiàn)在還沒弄😳)。

環(huán)境需求

  • Jdk (Elasticsearch需要)
  • ElasticSearch (用來存儲(chǔ)數(shù)據(jù))
  • Kinaba (用來操作ElasticSearch和數(shù)據(jù)可視化)
  • Python (編寫爬蟲)
  • Redis (數(shù)據(jù)排重)

這些東西可以去找相應(yīng)的教程安裝,我這里只有ElasticSearch的安裝😢點(diǎn)我獲取安裝教程

第一步,使用python的pip來安裝需要的插件(第一個(gè)坑在這兒)

1.tomd:將html轉(zhuǎn)換成markdown

pip3 install tomd

2.redis:需要python的redis插件

pip3 install redis

3.scrapy:框架安裝(坑)

  1、首先我是像上面一樣執(zhí)行了

pip3 install scrapy

   2、然后發(fā)現(xiàn)缺少gcc組件 error: command 'gcc' failed with exit status 1

   3、然后我就找啊找,找啊找,最后終于找到了正確的解決方法(期間試了很多錯(cuò)誤答案😭)。最終的解決辦法就是使用yum來安裝python34-devel,  這個(gè)python34-devel根據(jù)你自己的python版本來,可能是python-devel,是多少版本就將中間的34改成你的版本, 我的是3.4.6

yum install python34-devel

   4、安裝完成過后使用命令 scrapy 來試試吧。


第二步,使用scrapy來創(chuàng)建你的項(xiàng)目

輸入命令scrapy startproject scrapyDemo, 來創(chuàng)建一個(gè)爬蟲項(xiàng)目

liaochengdeMacBook-Pro:scrapy liaocheng$ scrapy startproject scrapyDemo
New Scrapy project 'scrapyDemo', using template directory '/usr/local/lib/python3.7/site-packages/scrapy/templates/project', created in:
	/Users/liaocheng/script/scrapy/scrapyDemo

You can start your first spider with:
	cd scrapyDemo
	scrapy genspider example example.com
liaochengdeMacBook-Pro:scrapy liaocheng$ 

使用genspider來生成一個(gè)基礎(chǔ)的spider,使用命令scrapy genspider demo juejin.im, 后面這個(gè)網(wǎng)址是你要爬的網(wǎng)站,我們先爬自己家的😂

liaochengdeMacBook-Pro:scrapy liaocheng$ scrapy genspider demo juejin.im
Created spider 'demo' using template 'basic'
liaochengdeMacBook-Pro:scrapy liaocheng$ 

查看生成的目錄結(jié)構(gòu)


第三步,打開項(xiàng)目,開始編碼

查看生成的的demo.py的內(nèi)容

# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
 name = 'demo' ## 爬蟲的名字
 allowed_domains = ['juejin.im'] ## 需要過濾的域名,也就是只爬這個(gè)網(wǎng)址下面的內(nèi)容
 start_urls = ['https://juejin.im/post/5c790b4b51882545194f84f0'] ## 初始url鏈接

 def parse(self, response): ## 如果新建的spider必須實(shí)現(xiàn)這個(gè)方法
 pass

可以使用第二種方式,將start_urls給提出來

# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
 name = 'demo' ## 爬蟲的名字
 allowed_domains = ['juejin.im'] ## 需要過濾的域名,也就是只爬這個(gè)網(wǎng)址下面的內(nèi)容

 def start_requests(self):
 start_urls = ['http://juejin.im/'] ## 初始url鏈接
 for url in start_urls:
  # 調(diào)用parse
  yield scrapy.Request(url=url, callback=self.parse)

 def parse(self, response): ## 如果新建的spider必須實(shí)現(xiàn)這個(gè)方法
 pass

編寫articleItem.py文件(item文件就類似java里面的實(shí)體類)

import scrapy

class ArticleItem(scrapy.Item): ## 需要實(shí)現(xiàn)scrapy.Item文件
 # 文章id
 id = scrapy.Field()

 # 文章標(biāo)題
 title = scrapy.Field()

 # 文章內(nèi)容
 content = scrapy.Field()

 # 作者
 author = scrapy.Field()

 # 發(fā)布時(shí)間
 createTime = scrapy.Field()

 # 閱讀量
 readNum = scrapy.Field()

 # 點(diǎn)贊數(shù)
 praise = scrapy.Field()

 # 頭像
 photo = scrapy.Field()

 # 評(píng)論數(shù)
 commentNum = scrapy.Field()

 # 文章鏈接
 link = scrapy.Field()

編寫parse方法的代碼

 def parse(self, response):
 # 獲取頁(yè)面上所有的url
 nextPage = response.css("a::attr(href)").extract()
 # 遍歷頁(yè)面上所有的url鏈接,時(shí)間復(fù)雜度為O(n)
 for i in nextPage:
  if nextPage is not None:
  # 將鏈接拼起來
  url = response.urljoin(i)
  # 必須是掘金的鏈接才進(jìn)入
  if "juejin.im" in str(url):
   # 存入redis,如果能存進(jìn)去,就是一個(gè)沒有爬過的鏈接
   if self.insertRedis(url) == True:
   # dont_filter作用是是否過濾相同url true是不過濾,false為過濾,我們這里只爬一個(gè)頁(yè)面就行了,不用全站爬,全站爬對(duì)對(duì)掘金不是很友好,我么這里只是用來測(cè)試的 
   yield scrapy.Request(url=url, callback=self.parse,headers=self.headers,dont_filter=False)

 # 我們只分析文章,其他的內(nèi)容都不管
 if "/post/" in response.url and "#comment" not in response.url:
  # 創(chuàng)建我們剛才的ArticleItem
  article = ArticleItem()

  # 文章id作為id
  article['id'] = str(response.url).split("/")[-1]

  # 標(biāo)題
  article['title'] = response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > h1::text").extract_first()

  # 內(nèi)容
  parameter = response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > div.article-content").extract_first()
  article['content'] = self.parseToMarkdown(parameter)

  # 作者
  article['author'] = response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > div:nth-child(6) > meta:nth-child(1)::attr(content)").extract_first()

  # 創(chuàng)建時(shí)間
  createTime = response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > div.author-info-block > div > div > time::text").extract_first()
  createTime = str(createTime).replace("年", "-").replace("月", "-").replace("日","")
  article['createTime'] = createTime

  # 閱讀量
  article['readNum'] = int(str(response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > div.author-info-block > div > div > span::text").extract_first()).split(" ")[1])

  # 點(diǎn)贊數(shù)
  article['badge'] = response.css("#juejin > div.view-container > main > div > div.article-suspended-panel.article-suspended-panel > div.like-btn.panel-btn.like-adjust.with-badge::attr(badge)").extract_first()

  # 評(píng)論數(shù)
  article['commentNum'] = response.css("#juejin > div.view-container > main > div > div.article-suspended-panel.article-suspended-panel > div.comment-btn.panel-btn.comment-adjust.with-badge::attr(badge)").extract_first()

  # 文章鏈接
  article['link'] = response.url

  # 這個(gè)方法和很重要(坑),之前就是由于執(zhí)行yield article, pipeline就一直不能獲取數(shù)據(jù)
  yield article

# 將內(nèi)容轉(zhuǎn)換成markdown
def parseToMarkdown(self, param):
 return tomd.Tomd(str(param)).markdown

# url 存入redis,如果能存那么就沒有該鏈接,如果不能存,那么就存在該鏈接
def insertRedis(self, url):
 if self.redis != None:
 return self.redis.sadd("articleUrlList", url) == 1
 else:
 self.redis = self.redisConnection.getClient()
 self.insertRedis(url)

編寫pipeline類,這個(gè)pipeline是一個(gè)管道,可以將所有yield關(guān)鍵字返回的數(shù)據(jù)都交給這個(gè)管道處理,但是需要在settings里面配置一下pipeline才行

from elasticsearch import Elasticsearch

class ArticlePipelines(object):
 # 初始化
 def __init__(self):
 # elasticsearch的index
 self.index = "article"
 # elasticsearch的type
 self.type = "type"
 # elasticsearch的ip加端口
 self.es = Elasticsearch(hosts="localhost:9200")

 # 必須實(shí)現(xiàn)的方法,用來處理yield返回的數(shù)據(jù)
 def process_item(self, item, spider):
 
 # 這里是判斷,如果是demo這個(gè)爬蟲的數(shù)據(jù)才處理
 if spider.name != "demo":
  return item

 result = self.checkDocumentExists(item)
 if result == False:
  self.createDocument(item)
 else:
  self.updateDocument(item)

 # 添加文檔
 def createDocument(self, item):
 body = {
  "title": item['title'],
  "content": item['content'],
  "author": item['author'],
  "createTime": item['createTime'],
  "readNum": item['readNum'],
  "praise": item['praise'],
  "link": item['link'],
  "commentNum": item['commentNum']
 }
 try:
  self.es.create(index=self.index, doc_type=self.type, id=item["id"], body=body)
 except:
  pass

 # 更新文檔
 def updateDocument(self, item):
 parm = {
  "doc" : {
  "readNum" : item['readNum'],
  "praise" : item['praise']
  }
 }

 try:
  self.es.update(index=self.index, doc_type=self.type, id=item["id"], body=parm)
 except:
  pass

 # 檢查文檔是否存在
 def checkDocumentExists(self, item):
 try:
  self.es.get(self.index, self.type, item["id"])
  return True
 except:
  return False

第四步,運(yùn)行代碼查看效果

使用scrapy list查看本地的所有爬蟲

liaochengdeMacBook-Pro:scrapyDemo liaocheng$ scrapy list
demo
liaochengdeMacBook-Pro:scrapyDemo liaocheng$ 

使用scrapy crawl demo來運(yùn)行爬蟲

 scrapy crawl demo

到kibana里面看爬到的數(shù)據(jù),執(zhí)行下面的命令可以看到數(shù)據(jù)

GET /article/_search
{
 "query": {
 "match_all": {}
 }
}
{
 "took": 7,
 "timed_out": false,
 "_shards": {
 "total": 5,
 "successful": 5,
 "skipped": 0,
 "failed": 0
 },
 "hits": {
 "total": 1,
 "max_score": 1,
 "hits": [
 {
 "_index": "article2",
 "_type": "type",
 "_id": "5c790b4b51882545194f84f0",
 "_score": 1,
 "_source": {}
 }
 ]
 }
}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Python中字符串的處理技巧分享

    Python中字符串的處理技巧分享

    這篇文章給大家分享了Python中字符串的處理技巧,包括拆分含有多種分隔符的字符串、判斷字符串a(chǎn)是否以字符串b開頭或結(jié)尾、調(diào)整字符串中文本的格式已經(jīng)將多個(gè)小字符串拼接成一個(gè)大的字符串等,感興趣的朋友們可以通過閱讀下文來學(xué)習(xí)。
    2016-09-09
  • 人臉識(shí)別具體案例

    人臉識(shí)別具體案例

    出于興趣和對(duì)IU的喜愛,筆者花了幾天嘗試用爬蟲從百度圖片獲取人物圖片并下載,利用深度神經(jīng)網(wǎng)絡(luò)從其中識(shí)別出人,并將圖片保存至文件夾。若讀者有興趣可以參考下
    2021-04-04
  • 解決python打不開文件(文件不存在)的問題

    解決python打不開文件(文件不存在)的問題

    今天小編就為大家分享一篇解決python打不開文件(文件不存在)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python必知必會(huì)之os模塊實(shí)例詳解

    Python必知必會(huì)之os模塊實(shí)例詳解

    os模塊是Python標(biāo)準(zhǔn)庫(kù)中整理文件和目錄最為常用的模塊,該模塊提供了非常豐富的方法用來處理文件和目錄,下面這篇文章主要給大家介紹了關(guān)于Python必知必會(huì)之os模塊的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • python如何通過twisted實(shí)現(xiàn)數(shù)據(jù)庫(kù)異步插入

    python如何通過twisted實(shí)現(xiàn)數(shù)據(jù)庫(kù)異步插入

    這篇文章主要為大家詳細(xì)介紹了python如何通過twisted實(shí)現(xiàn)數(shù)據(jù)庫(kù)異步插入,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python 協(xié)程與 JavaScript 協(xié)程的對(duì)比

    Python 協(xié)程與 JavaScript 協(xié)程的對(duì)比

    當(dāng)漸漸對(duì) JavaScript 了解后,一查發(fā)現(xiàn) Python 和 JavaScript 的協(xié)程發(fā)展史簡(jiǎn)直就是一毛一樣!接下來小編就大致做下橫向?qū)Ρ群涂偨Y(jié),便于對(duì)這兩個(gè)語(yǔ)言有興趣的新人理解和吸收。
    2021-09-09
  • Face++ API實(shí)現(xiàn)手勢(shì)識(shí)別系統(tǒng)設(shè)計(jì)

    Face++ API實(shí)現(xiàn)手勢(shì)識(shí)別系統(tǒng)設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了Face++ API實(shí)現(xiàn)手勢(shì)識(shí)別系統(tǒng)設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • python3?chromedrivers簽到的簡(jiǎn)單實(shí)現(xiàn)

    python3?chromedrivers簽到的簡(jiǎn)單實(shí)現(xiàn)

    本文主要介紹了python3?chromedrivers簽到的簡(jiǎn)單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • python抓取京東商城手機(jī)列表url實(shí)例代碼

    python抓取京東商城手機(jī)列表url實(shí)例代碼

    python抓取京東商城手機(jī)列表url實(shí)例分享,大家參考使用吧
    2013-12-12
  • 關(guān)于python中第三方庫(kù)交叉編譯的問題

    關(guān)于python中第三方庫(kù)交叉編譯的問題

    這篇文章主要介紹了python及第三方庫(kù)交叉編譯,通過交叉編譯工具,我們就可以在CPU能力很強(qiáng)、存儲(chǔ)控件足夠的主機(jī)平臺(tái)上(比如PC上)編譯出針對(duì)其他平臺(tái)的可執(zhí)行程序,需要的朋友可以參考下
    2022-09-09

最新評(píng)論