一步步教你用python的scrapy编写一个爬虫

介绍

本文将介绍我是如何在python爬虫里面一步一步踩坑,然后慢慢走出来的,期间碰到的所有问题我都会详细说明,让大家以后碰到这些问题时能够快速确定问题的来源,后面的代码只是贴出了核心代码,更详细的代码暂时没有贴出来。

流程一览

首先我是想爬某个网站上面的所有文章内容,但是由于之前没有做过爬虫(也不知道到底那个语言最方便),所以这里想到了是用python来做一个爬虫(毕竟人家的名字都带有爬虫的含义😄),我这边是打算先将所有从网站上爬下来的数据放到ElasticSearch里面, 选择ElasticSearch的原因是速度快,里面分词插件,倒排索引,需要数据的时候查询效率会非常好(毕竟爬的东西比较多😄),然后我会将所有的数据在ElasticSearch的老婆kibana里面将数据进行可视化出来,并且分析这些文章内容,可以先看一下预期可视化的效果(上图了),这个效果图是kibana6.4系统给予的帮助效果图(就是说你可以弄成这样,我也想弄成这样😁)。后面我会发一个dockerfile上来(现在还没弄😳)。

环境需求

  • Jdk (Elasticsearch需要)
  • ElasticSearch (用来存储数据)
  • Kinaba (用来操作ElasticSearch和数据可视化)
  • Python (编写爬虫)
  • Redis (数据排重)

这些东西可以去找相应的教程安装,我这里只有ElasticSearch的安装😢点我获取安装教程

第一步,使用python的pip来安装需要的插件(第一个坑在这儿)

1.tomd:将html转换成markdown

pip3 install tomd

2.redis:需要python的redis插件

pip3 install redis

3.scrapy:框架安装(坑)

1、首先我是像上面一样执行了

pip3 install scrapy

2、然后发现缺少gcc组件 error: command 'gcc' failed with exit status 1

3、然后我就找啊找,找啊找,最后终于找到了正确的解决方法(期间试了很多错误答案😭)。最终的解决办法就是使用yum来安装python34-devel,  这个python34-devel根据你自己的python版本来,可能是python-devel,是多少版本就将中间的34改成你的版本, 我的是3.4.6

yum install python34-devel

4、安装完成过后使用命令 scrapy 来试试吧。

第二步,使用scrapy来创建你的项目

输入命令scrapy startproject scrapyDemo, 来创建一个爬虫项目

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来生成一个基础的spider,使用命令scrapy genspider demo juejin.im, 后面这个网址是你要爬的网站,我们先爬自己家的😂

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

查看生成的目录结构

第三步,打开项目,开始编码

查看生成的的demo.py的内容

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

class DemoSpider(scrapy.Spider):
 name = 'demo' ## 爬虫的名字
 allowed_domains = ['juejin.im'] ## 需要过滤的域名,也就是只爬这个网址下面的内容
 start_urls = ['https://juejin.im/post/5c790b4b51882545194f84f0'] ## 初始url链接

 def parse(self, response): ## 如果新建的spider必须实现这个方法
 pass

可以使用第二种方式,将start_urls给提出来

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

class DemoSpider(scrapy.Spider):
 name = 'demo' ## 爬虫的名字
 allowed_domains = ['juejin.im'] ## 需要过滤的域名,也就是只爬这个网址下面的内容

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

 def parse(self, response): ## 如果新建的spider必须实现这个方法
 pass

编写articleItem.py文件(item文件就类似java里面的实体类)

import scrapy

class ArticleItem(scrapy.Item): ## 需要实现scrapy.Item文件
 # 文章id
 id = scrapy.Field()

 # 文章标题
 title = scrapy.Field()

 # 文章内容
 content = scrapy.Field()

 # 作者
 author = scrapy.Field()

 # 发布时间
 createTime = scrapy.Field()

 # 阅读量
 readNum = scrapy.Field()

 # 点赞数
 praise = scrapy.Field()

 # 头像
 photo = scrapy.Field()

 # 评论数
 commentNum = scrapy.Field()

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

编写parse方法的代码

 def parse(self, response):
 # 获取页面上所有的url
 nextPage = response.css("a::attr(href)").extract()
 # 遍历页面上所有的url链接,时间复杂度为O(n)
 for i in nextPage:
  if nextPage is not None:
  # 将链接拼起来
  url = response.urljoin(i)
  # 必须是掘金的链接才进入
  if "juejin.im" in str(url):
   # 存入redis,如果能存进去,就是一个没有爬过的链接
   if self.insertRedis(url) == True:
   # dont_filter作用是是否过滤相同url true是不过滤,false为过滤,我们这里只爬一个页面就行了,不用全站爬,全站爬对对掘金不是很友好,我么这里只是用来测试的
   yield scrapy.Request(url=url, callback=self.parse,headers=self.headers,dont_filter=False)

 # 我们只分析文章,其他的内容都不管
 if "/post/" in response.url and "#comment" not in response.url:
  # 创建我们刚才的ArticleItem
  article = ArticleItem()

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

  # 标题
  article['title'] = response.css("#juejin > div.view-container > main > div > div.main-area.article-area.shadow > article > h1::text").extract_first()

  # 内容
  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()

  # 创建时间
  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])

  # 点赞数
  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()

  # 评论数
  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

  # 这个方法和很重要(坑),之前就是由于执行yield article, pipeline就一直不能获取数据
  yield article

# 将内容转换成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类,这个pipeline是一个管道,可以将所有yield关键字返回的数据都交给这个管道处理,但是需要在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")

 # 必须实现的方法,用来处理yield返回的数据
 def process_item(self, item, spider):

 # 这里是判断,如果是demo这个爬虫的数据才处理
 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

第四步,运行代码查看效果

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

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

使用scrapy crawl demo来运行爬虫

 scrapy crawl demo

到kibana里面看爬到的数据,执行下面的命令可以看到数据

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": {}
 }
 ]
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • 零基础写python爬虫之使用Scrapy框架编写爬虫

    网络爬虫,是在网上进行数据抓取的程序,使用它能够抓取特定网页的HTML数据.虽然我们利用一些库开发一个爬虫程序,但是使用框架可以大大提高效率,缩短开发时间.Scrapy是一个使用Python编写的,轻量级的,简单轻巧,并且使用起来非常的方便.使用Scrapy可以很方便的完成网上数据的采集工作,它为我们完成了大量的工作,而不需要自己费大力气去开发. 首先先要回答一个问题. 问:把网站装进爬虫里,总共分几步? 答案很简单,四步: 新建项目 (Project):新建一个新的爬虫项目 明确目标(Item

  • 详解python3 + Scrapy爬虫学习之创建项目

    最近准备做一个关于scrapy框架的实战,爬取腾讯社招信息并存储,这篇博客记录一下创建项目的步骤 pycharm是无法创建一个scrapy项目的 因此,我们需要用命令行的方法新建一个scrapy项目 请确保已经安装了scrapy,twisted,pypiwin32 一:进入你所需要的路径,这个路径存储你创建的项目 我的将放在E盘的Scrapy目录下 二:创建项目:scrapy startproject ***(这个是项目名) 这样就创建好了一个名为tencent的项目 三:进入项目新建一个爬虫:

  • Python3环境安装Scrapy爬虫框架过程及常见错误

    Windows •安装lxml 最好的安装方式是通过wheel文件来安装,http://www.lfd.uci.edu/~gohlke/pythonlibs/,从该网站找到lxml的相关文件.假如是Python3.5版本,WIndows 64位系统,那就找到lxml‑3.7.2‑cp35‑cp35m‑win_amd64.whl 这个文件并下载,然后通过pip安装. 下载之后,运行如下命令安装: pip3 install wheel pip3 install lxml‑3.7.2‑cp35‑cp3

  • Python爬虫框架Scrapy安装使用步骤

    一.爬虫框架Scarpy简介Scrapy 是一个快速的高层次的屏幕抓取和网页爬虫框架,爬取网站,从网站页面得到结构化的数据,它有着广泛的用途,从数据挖掘到监测和自动测试,Scrapy完全用Python实现,完全开源,代码托管在Github上,可运行在Linux,Windows,Mac和BSD平台上,基于Twisted的异步网络库来处理网络通讯,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片. 二.Scrapy安装指南 我们的安装步骤假设你已经安装一下内容:<1>

  • python scrapy爬虫代码及填坑

    涉及到详情页爬取 目录结构: kaoshi_bqg.py import scrapy from scrapy.spiders import Rule from scrapy.linkextractors import LinkExtractor from ..items import BookBQGItem class KaoshiBqgSpider(scrapy.Spider): name = 'kaoshi_bqg' allowed_domains = ['biquge5200.cc'] s

  • 浅析python实现scrapy定时执行爬虫

    项目需要程序能够放在超算中心定时运行,于是针对scrapy写了一个定时爬虫的程序main.py ,直接放在scrapy的存储代码的目录中就能设定时间定时多次执行. 最简单的方法:直接使用Timer类 import time import os while True: os.system("scrapy crawl News") time.sleep(86400) #每隔一天运行一次 24*60*60=86400s或者,使用标准库的sched模块 import sched #初始化sch

  • Python 利用scrapy爬虫通过短短50行代码下载整站短视频

    近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题. 因为这个事儿,勾起了我另一个念头,这不最近一直想把python爬虫方面的知识梳理梳理吗,干脆借机行事,正凑着短视频火热的势头,做一个短视频的爬虫好了,中间用到什么知识就理一理. 我喜欢把事情说得很直白,如果恰好有初入门的朋友想了解爬虫的技术,可以将就看看,或许对你的认识会有提升.如果有高手路过,

  • 一步步教你用python的scrapy编写一个爬虫

    介绍 本文将介绍我是如何在python爬虫里面一步一步踩坑,然后慢慢走出来的,期间碰到的所有问题我都会详细说明,让大家以后碰到这些问题时能够快速确定问题的来源,后面的代码只是贴出了核心代码,更详细的代码暂时没有贴出来. 流程一览 首先我是想爬某个网站上面的所有文章内容,但是由于之前没有做过爬虫(也不知道到底那个语言最方便),所以这里想到了是用python来做一个爬虫(毕竟人家的名字都带有爬虫的含义

  • python中用Scrapy实现定时爬虫的实例讲解

    一般网站发布信息会在具体实现范围内发布,我们在进行网络爬虫的过程中,可以通过设置定时爬虫,定时的爬取网站的内容.使用python爬虫框架Scrapy框架可以实现定时爬虫,而且可以根据我们的时间需求,方便的修改定时的时间. 1.Scrapy介绍 Scrapy是python的爬虫框架,用于抓取web站点并从页面中提取结构化的数据.任何人都可以根据需求方便的修改.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. 2.使用Scrapy框架定时爬取 import time from scrapy

  • Python 如何手动编写一个自己的LRU缓存装饰器的方法实现

    LRU缓存算法,指的是近期最少使用算法,大体逻辑就是淘汰最长时间没有用的那个缓存,这里我们使用有序字典,来实现自己的LRU缓存算法,并将其包装成一个装饰器. 1.首先创建一个my_cache.py文件 编写自己我们自己的LRU缓存算法,代码如下: import time from collections import OrderedDict ''' 基于LRU,近期最少用缓存算法写的装饰器. ''' class LRUCacheDict: def __init__(self, max_size=

  • 一步步教你用Python实现2048小游戏

    前言 2048游戏规则:简单的移动方向键让数字叠加,并且获得这些数字每次叠加后的得分,当出现2048这个数字时游戏胜利.同时每次移动方向键时,都会在这个4*4的方格矩阵的空白区域随机产生一个数字2或者4,如果方格被数字填满了,那么就GameOver了. 主逻辑图 逻辑图解:黑色是逻辑层,蓝色是外部方法,红色是类内方法,稍后即可知道~ 下面容我逐行解释主逻辑main()函数,并且在其中穿叉外部定义的函数与类. 主逻辑代码解读(完整代码见文末) 主逻辑main如下,之后的是对主函数中的一些方法的解读

  • 一步步教你用python给女朋友写个微信自动提醒的程序

    目录 前言 第一步:文本内容的确定 第二步:微信端发送消息的实现 第三步:定时任务的设置 总结 前言 事件背景是经常有很多琐碎的事情需要在某个时间点去做,光靠人力去记,容易出现偏差,尤其是对容易迷糊的选手. 所以动手写了一套代码,可以按需要通过微信发送消息,不论是给自己充当自动提醒的备忘录还是给其他人发送定时消息,都可以在这套代码的基础上实现. 首先放上最终成果示例: 图中的文字都是可以根据自身需要而进行修改的,所以文章中附上的代码也只是抛砖引玉,读者可以根据自身需要而进行调整.本篇文章会分三个

  • Python中Scrapy框架的入门教程分享

    目录 前言 安装Scrapy 创建一个Scrapy项目 创建一个爬虫 运行爬虫 结论 前言 Scrapy是一个基于Python的Web爬虫框架,可以快速方便地从互联网上获取数据并进行处理.它的设计思想是基于Twisted异步网络框架,可以同时处理多个请求,并且可以使用多种处理数据的方式,如提取数据.存储数据等. 本教程将介绍如何使用Scrapy框架来编写一个简单的爬虫,从而让您了解Scrapy框架的基本使用方法. 安装Scrapy 首先,您需要在您的计算机上安装Scrapy框架.您可以使用以下命

  • python 6.7 编写printTable()函数表格打印(完整代码)

    编写一个名为printTable()的函数,它接受字符串的列表的列表,将它显示在组织良好的表格中,每列右对齐.假定所有内层列表都包含同样数目的字符串 输入: tableData = [['apple','orange','cherry','banana'], ['Alice','Bob','Cathy','David'], ['dog','cat','bird','duck']] 输出: 因此首先要找到每一个内层列表中最长的字符串长度,因为我们可以对比tableData列表和输出的截图.不难发现

  • 分步骤教你用python一步步提取PPT中的图片

    目录 一.实现原理 二.提取PPT中的图片 1.打开压缩包 2.解压文件 三.提取PPT中的图片 一.实现原理 其实实现原理很简单,我们的pptx文件其实是一个压缩包.我们可以直接修改pptx文件的后缀,改成zip然后解压,比如下面这个: 这是解压后的文件.我们可以在ppt目录下找到一个media目录,这个目录下就是我们要的图片的.这个目录包含了PPT的所有多媒体文件. 知道这点后,我们就可以选择用Python来解压出PPT中的media目录就可以提取出所有图片了. 二.提取PPT中的图片 1.

  • 手把手教你进行Python虚拟环境配置教程

    /1 前言/ 咱们今天就来说一下Python的虚拟环境,可能有的小伙伴会疑惑,Python的虚拟环境有什么用呢?接下来我们一起来探讨一下. /2 虚拟环境的作用/ 咱们今天就来说一下Python的虚拟环境,可能有的小伙伴会疑惑,Python的虚拟环境有什么用呢?接下来我们一起来探讨一下. 我们先来举个例子,来说明为什么需要虚拟环境.我们在学习Python的时候,可能会学到越来越多的第三方库,比如爬虫,我们需要安装requests,可能学着学着,我们还需要安装bs4,或者又学着学着,我们还需要安装

随机推荐