Git Product home page Git Product logo

daguerrespider's Introduction

发出前两篇Python实战的文章之后,有同学和我反映:你的想法很牛逼,可是我就是看不懂你写的是什么,我Python不熟悉,看起来有点吃力。我细细一琢磨,这点是个问题。对于熟悉Python的同学,能够看懂我思路,但是对于那些没有Python基础,或者对Python不熟悉的同学,这样直接扔过来,可能会让他们失望而归。所以,这回我弄了一期手把手的实战教程,同时,在文章中遇到的知识点,还会有提供链接。完全对新手有好。

在前两篇Python实战「用代码来访问1024网站」「用Scrapy编写“1024网站种子吞噬爬虫”」收到了大家的一致好评,可能文章写得比较匆忙,有些术语可能对于Python的初级玩家不是很好理解。所以,我特别准备了一下,用超级详细的解说,细化到每一步,提供查询链接等方法,为Python初级玩家,Python小白和对Scrapy框架不熟悉的同学,的制作了这篇手把手Python实战教程:用Scrapy爬取下载达盖尔社区的资源。

好了,废话不多说,学习代码就是要学以致用的。不能写了一遍代码就让代码吃灰。下面就跟我一起来搞吧。

小草网站是个好网站,我们这次实战的结果,是要把“达盖尔旗帜”里面的帖子爬取下来,将帖子的图片保存到本地,同时将帖子的一些相关信息,写入到本地的MongoDB中。这么乍一听,感觉我们做的事情好像挺多的,别慌,我带你慢慢的一步一步来搞起,问题不是很大。

手把手 Step By Stefp

Scrapy可以通过pip来安装:

$ pip install scrapy

接下来,我们去事先建好的工程目录里面,创建Scrapy的项目。这里,我们先看一下Scrapy的命令行怎么用,输入$ scray -help出来

scrapy帮助文档

看到,创建scrapy的工程的命令是$ scrapy startproject <name>创建完的结果如下:

创建工程成功

OK,这个时候,我们的目录内容变成了如下结构:

工程结构目录

下一步就是创建我们的爬虫,还是依靠Scrapy本身自带的命令来创建。输入Scrapy自带四种爬虫模板:basiccrawlcsvfeedxmlfeed四种。我们这里选择basic。

$ scrapy genspider --template=basic superspider bc.ghuws.men

创建成功,会出现以下提示:

创建爬虫

这时候我们的工程目录就变成了这个样子:

有了爬虫的工程目录

看到我们的工程里面多了一个spiders文件夹,里面有一个superspider.py文件,这个就是我们这次程序的主角。我们来看,这个可爱的小虫子刚生下来是长这个样子的:

爬虫

这里呢,就简单说一下:

  • name - 是咱们的爬虫名字,这个主要是在运行爬虫的时候会用到。
  • allowed_domains - 是在scrapy自带的OffsiteMiddleware中用到的。Scrapy默认会开启OffsiteMiddleware插件,不在此允许范围内的域名就会被过滤,而不会进行爬取。
  • start_urls - 爬虫开始爬取的url。
  • parse()方法 - 这个就是处理请求结果的。我们具体的爬虫逻辑大部分就是在这里写。

好了,废话不多说,既然start_urls是用来做爬虫开始爬取的第一个url,那么我们就应该把这里面的数值换成达盖尔社区的地址,然后我们看一下在parse()里面返回的值是什么。运行方法,就是输入$ scrapy crawl superspider指令即可:

爬虫v0.1

response对象

response对象的body

我们看到,这个response是一个HtmlResponse类,它里面的text属性,里面的字符串就是网页的html文件。OK,这一步结束之后,我们下一步就想办法怎样能够解析html网页了。Scrapy是提供了html对象的解析的,它有一个selector类,可以解析html,同时,里面还支持xpath语法的查找和css的查找。但是这个个人感觉不是很好用,我推荐用BeautifulSoup4库。安装方法只需要$ pip install beautifulsoup4。我们这里需要用这个来解析html,所以讲BeautifulSoup4导进来,在解析,然后我们就会得到一个beasutifulsoup对象。之后,我们就要在这个对象里面寻找我们需要解析的对象。

BeautifulSoup的对象

bs解析

目前网页已经解析好了,下一步就是要在html文件中,找到每一个帖子的信息。我们回头来看html文件的源码,可以看到,每一个帖子其实都是在一个<tr>tag里面,其实我们需要的东西,就是下图红色框框里面圈的<a>tag。

html页面

这里,我们发现,每一个帖子的链接入口,也就是<a>tag是有两个特性,一个是有id值,另一个是有href值。所以,我们要针对soup对象,调用find_all()方法来寻找有特定内容的所有标签。

抓取所有的 a 标签

a 标签结果

我们得到了一个 a_list结果,这是一个list对象,长度102。在这些数据中,有些结果是我们不要的,比如000到007位置的这几个数据,他们在网页中对应的是版规之类的帖子信息,和我们想要的东西不一样,所以,在拿到这个a_list数据,我们需要进行一下筛选。

筛选的过程必不可少,筛选的方法有很多种,我们这里就做的简单一点,只选取18年的帖子。为什么会是18年的帖子啊?少年你看,这一列href的值:

href的区别

第二个数字“1805”,应该就是“年份+月份”。如果不信,则可以跳到比如论坛100页,看到的是16年3月份的帖子,这里面随便检查一个连接的href值,是“1603”。这就印证了我们的想法是正确的。好,按照这个筛选18年的帖子的思路,我们来筛选一下a_list

筛选结果diamante

筛选完的结果

看到打印的结果却是是18年的帖子。但是目前的href并不是帖子真正的url。真正的url应该长这个样子:

http://bc.ghuws.men/htm_data/16/1805/3126577.html

所以,我们这里得进行拼接。对比上面的url,我们目前只有后半部分,前半部分其实是社区网站的root url。那么我们在settings.py文件里面添加一个ROOT_URL变量,并将这个变量导入到我们的spider中即可。代码就变成了这样。为了方便,咱们还可以把帖子的id,也就是.html前面的那个数字也摘出来,方便日后使用。

拼凑出帖子地址

目前为止,我们拿到了帖子的id和帖子的url。我们的最终目的是要下载图片,所以,我们得让爬虫去按照帖子的url去爬取他们。爬虫需要进入第二层。这里,我们需要使用yield函数,调用scrapy.Request方法,传入一个callback,在callback中做解析。

二级爬虫

现在我们已经进入了每一个帖子的内部,我们现在还没有拿到的信息有帖子的标题和帖子的图片。还是和parse()的步骤一样,这个时候,我们就该分析帖子的html文件了。 我们先找标题。看到html文件中,标题对应的是一个<h4>标签。

post的html

那这就简单了,我们只需要找到所有的<h4>标签,然后看标题是第几个就好。接下来是图片了。每个帖子用的图床都不一样,所以图片部分,我们先来看一下结构:

图片的标签1

图片的标签2

大概就是这两种,我们看到,图片的标签是<input>,关键点就在type=image上面,所以我们尝试着看看能不能根据这个来找到图片的地址。

二级爬虫完成

我们简单测试一下,看看运行效果:

爬取帖子页面的图片运行效果

完全没有问题,看着好爽。这时候,我们看结果,会发现,我们抓取到的image,会有一两个的图床是不一样的。

运行结果(部分)

打开也会看到这个图片,里面的内容也和其他的图片不一样,并且这个图片不是我们想要的。所以,这里我们得做一下过滤。我这里的方法就是要从找到的image_list里面,把少数图床不一样的图片url给过滤掉。一般看来,都是找到的第一个图片不是我们想要的,所以我们这里只是判断一下第一个和第二个是否一样就可以。

筛选图片

这样打印出来的结果就没有问题喽。

哈哈,现在我们已经拿到了帖子的id,标题,帖子的url地址,还有帖子里面图片的url地址。离我们的目标又近了一步。我之前说过,我们的目标是要把每张图片都保存在本地,目前我们只是拿到了每张图片的url。所以,我们需要把图片都下载下载下来。

其实,当拿到图片的URL进行访问的时候,通过http返回的数据,虽然是字符串的格式,但是只要将这些字符串保存成指定的图片格式,我们在本地就可以按照图片的解析来打开。这里,我们拿到帖子的image_list,就可以在yield出一层请求,这就是爬虫的第三层爬取了。

红框框的很关键

同时,在第三层爬虫里面,我们还需要将访问回来的图片保存到本地目录。那么代码就长这个样子:

三级爬虫

在上面第二次爬取函数的最后,有个地方需要注意一下,就是上图中红色框框圈出来的地方。这里需要加上dont_filter=True。否则就会被Scrapy给过滤掉。因为图床的地址,并未在我们刚开始的allow_domain里面。加上这个就可以正常访问了。

这样运行一遍,我们的本地目录里面就会有保存好的下载照片了。

图片保存节选

本地文件夹保存的下载好的图片

我们还有个问题,就是我们需要将每个帖子的信息(id,title,url,image)都保存到本地的数据库中。这个该怎么做?

别慌,这个其实很简单。

首先,我们得针对每个帖子,建立一个Scrapy的item。需要在items.py里面编写代码:

scrapy item

写好之后,我们需要在爬虫里面引入这个类,在第二层解析函数中,构建好item,最后yield出来。这里,yield出来,会交给Scrapy的pipeline来处理。

生成item

yield出来的item会进入到pipeline中。但是这里有个前提,就是需要将pipeline在settings.py中设置。

将pipeline添加到settings里面

pipeline中我们先打印帖子的id,看看数据能不能够传入到这里

pipeline

运行:

pipeline完美运行

看到数据是完全可以过来的,而且在Scrapy的log中,会打印出来每一个item里面的信息。

我们如果想把数据保存到MongoDB中,这个操作就应该是在pipeline中完成的。Scrapy之所以简历pipeline就是为了针对每个item,如果有特殊的处理,就应该在这里完成。那么,我们应该首先导入pymongo库。然后,我们需要在pipeline的__init__()初始化进行连接数据库的操作。整体完成之后,pipeline应该长这个样子:

pipeline代码

那么我们来测试一下数据是否能够存入到MongoDB中。首先,在terminal中,通过命令$ sudo mongod来启动MongoDB。

启动MondoDB

那么运行一下,看一下效果:

MongoDB里面保存的数据

可以看到,左侧,有名为Daguerre的数据库,里面有名为postTable的表,而且我们的数据成功的写入了数据库中。数据的格式如图所展示,和我们预期的结果是一样的。

目前为止,我们完成了:从一页page中,获得所有帖子的url,然后进入每个帖子,再在帖子中,爬取每个帖子的图片,下载保存到本地,同时把帖子的信息存储到数据库中。

但是,这里你有没有发现一个问题啊?我们只爬取了第一页的数据,那如何才能爬取第二页,第三页,第N页的数据呢?

别慌,只需要简单的加几行代码即可。在我们的spider文件中的parse()方法地下,加一个调用自己的方法即可,只不过,传入的url得是下一页的url,所以,我们这里得拼凑出下一页的url,然后再次调用parse()方法即可。这里为了避免无限循环,我们设定一个最大页数MAX_PAGES为3,即爬取前三页的数据。

爬取下一个页面

OK,这样就完事儿了,这个达盖尔旗帜的爬虫就写好了。我们运行一下瞅瞅效果:

Boom,运行效果爆炸

是不是非常的酷炫?再来看看我们的运行结果:

爬虫运行结果1

爬虫运行结果2

爬虫运行结果3

只能说,战果累累,有图有真相。

其实,这个程序,可以加入middleware,为http请求提供一些Cookie和User-Agents来防止被网站封。同时,在settings.py文件中,我们也可以设置一下DOWNLOAD_DELAY来降低一下单个的访问速度,和CONCURRENT_REQUESTS来提升一下访问速度。

DOWNLOAD_DELAY

CONCURRENT_REQUESTS

就像之前EpicScrapy1024项目里面一样。喜欢的同学,可以去借鉴那个项目代码,然后融会贯通,自成一派,爬遍天下网站,无敌是多么的寂8 寞~~~~

好啦,能看到这里说明少年你很用心,很辛苦,是一个可塑之才。

废话不说,看到这里是有奖励的。关注“皮克啪的铲屎官”,回复“达盖尔”,即可获得项目源码和说明文档。同时,可以在下面的菜单中,找到“Python实战”按钮,能够查看以往文章,篇篇都非常精彩的哦~

扯扯皮,我觉得学习编程最大的动力就是爱好,其实干什么事情都是。爱好能够提供无线的动力,让人元气满满的往前冲刺。代码就是要方便作者,方便大家。写出来的代码要有用处,而且不要吃灰。这样的代码才是好代码。欢迎大家关注我的公众号,“皮克啪的铲屎官”,之后我会退出Python数据分析的内容,可能会结合量化交易之类的东西。

最后,来贴一张达盖尔的图片,纪念一下这位为人类做出杰出贡献的人。

达盖尔本尊

推荐阅读:

【Python实战】用Scrapy编写“1024网站种子吞噬爬虫”,送福利
【Python实战】用代码来访问1024网站,送福利

关注公众号“皮克啪的铲屎官”,回复“达盖尔”就可以获得惊喜

daguerrespider's People

Contributors

swyftg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

daguerrespider's Issues

为什么运行以后out里什么都没有?

G:\DaguerreSpider-master\Daguerre>scrapy crawl superspider
2021-03-21 14:17:09 [scrapy.utils.log] INFO: Scrapy 2.4.1 started (bot: Daguerre)
2021-03-21 14:17:09 [scrapy.utils.log] INFO: Versions: lxml 4.6.2.0, libxml2 2.9.5, cssselect 1.1.0, parsel 1.6.0, w3lib 1.22.0, Twisted 21.2.0, Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)], pyOpenSSL 20.0.1 (OpenSSL 1.1.1j 16 Feb 2021), cryptography 3.4.6, Platform Windows-10-10.0.19041-SP0
2021-03-21 14:17:09 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.selectreactor.SelectReactor
2021-03-21 14:17:09 [scrapy.crawler] INFO: Overridden settings:
{'BOT_NAME': 'Daguerre',
'CONCURRENT_REQUESTS': 32,
'DOWNLOAD_DELAY': 1,
'NEWSPIDER_MODULE': 'Daguerre.spiders',
'ROBOTSTXT_OBEY': True,
'SPIDER_MODULES': ['Daguerre.spiders']}
2021-03-21 14:17:09 [scrapy.extensions.telnet] INFO: Telnet Password: 8853f12029b3d17c
2021-03-21 14:17:09 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
'scrapy.extensions.telnet.TelnetConsole',
'scrapy.extensions.logstats.LogStats']
2021-03-21 14:17:10 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
'scrapy.downloadermiddlewares.retry.RetryMiddleware',
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
'scrapy.downloadermiddlewares.stats.DownloaderStats']
2021-03-21 14:17:10 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
'scrapy.spidermiddlewares.referer.RefererMiddleware',
'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
'scrapy.spidermiddlewares.depth.DepthMiddleware']
2021-03-21 14:17:11 [scrapy.middleware] INFO: Enabled item pipelines:
['Daguerre.pipelines.DaguerrePipeline']
2021-03-21 14:17:11 [scrapy.core.engine] INFO: Spider opened
2021-03-21 14:17:11 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2021-03-21 14:17:11 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2021-03-21 14:17:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://cl.286x.xyz/robots.txt> (referer: None)
2021-03-21 14:17:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://cl.286x.xyz/thread0806.php?fid=16&search=&page=1> (referer: None)
2021-03-21 14:17:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://cl.286x.xyz/thread0806.php?fid=16&search=&page=2> (referer: https://cl.286x.xyz/thread0806.php?fid=16&search=&page=1)
2021-03-21 14:17:16 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://cl.286x.xyz/thread0806.php?fid=16&search=&page=3> (referer: https://cl.286x.xyz/thread0806.php?fid=16&search=&page=2)
2021-03-21 14:17:16 [scrapy.core.engine] INFO: Closing spider (finished)
2021-03-21 14:17:16 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 1282,
'downloader/request_count': 4,
'downloader/request_method_count/GET': 4,
'downloader/response_bytes': 37408,
'downloader/response_count': 4,
'downloader/response_status_count/200': 4,
'elapsed_time_seconds': 5.242255,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2021, 3, 21, 6, 17, 16, 313344),
'log_count/DEBUG': 4,
'log_count/INFO': 10,
'request_depth_max': 2,
'response_received_count': 4,
'robotstxt/request_count': 1,
'robotstxt/response_count': 1,
'robotstxt/response_status_count/200': 1,
'scheduler/dequeued': 3,
'scheduler/dequeued/memory': 3,
'scheduler/enqueued': 3,
'scheduler/enqueued/memory': 3,
'start_time': datetime.datetime(2021, 3, 21, 6, 17, 11, 71089)}
2021-03-21 14:17:16 [scrapy.core.engine] INFO: Spider closed (finished)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.