文章目录


文章目录

  • 文章目录
  • 前言
  • 一、分析数据源
    • 思路分析
  • 二、代码部分
  • 总结

前言

最近写了一个词典网站的爬虫,响应以及获取数据的方式非常的简单,本以为会是个轻松的爬虫脚本,没曾想出了很多意料之外的问题,这样使得我对代码本身有了更加清晰的认知。


提示:以下是本篇文章正文内容,下面案例可供参考

一、分析数据源

在爬取所需的资源时,首当其冲的就是要确认数据来源,数据具体在什么位置,数据的目录页,分类所进入的逻辑是什么等等。笔者在编写一个爬虫脚本之前往往会先思考这个问题,只要将逻辑考虑的清晰顺畅,后面我们所做的代码编写会轻松很多。

目标网站:https://ctext.org/zhs

思路分析

首先进入主页,引入眼帘的是如下页面:

左侧是网站的目录,我们的目的是拿到该词典的古文双译句子。按照该网站的目录情况,似乎该词典网站的数据大体上分为"先秦两汉"和"汉代之后"两类,我们尝试点进去看看。





注意这里url的变化,在进入"先秦两汉"页面后,首先网站的url发生了变化,多了一个/pre-qin-and-han/部分,这次可以初步判定这是一个get请求。并且在切换英文繁体的时候,仅是ulr的后缀发生了变化,而且我们发现在英文和繁体的页面中,会直接带每一句其相应的英文翻译,这样的话,我们最终的目标页就确定了,我们只需要进入该页面就可以拿到我们所需的内容。

再其次我们发现,在"先秦两汉"的页面中,似乎其下的分类,例如:论语,孟子等等都是以及加载好了,似乎我们并不需要经过"论语"这一部分。我们在"先秦两汉"的页面中就可以拿到每一部古文经典中每一篇的url。我们打开F12调试验证一下:


果然,验证了之前我们的猜想,可是这里似乎还多了例如:儒家,墨家,道家等这样“先秦两汉”次级目录下的url,并且在这里的页面规则下,我们利用xpath提取相应的href时会包含它们。我们初步的思路是跳过这一次级目录,直接取"儒家,墨家,道家等"其下的每一篇的url,那会不会有影响呢?我们分别点进两种页面看看。


答案是不会,即使我们将"先秦两汉"页面中的包含了"论语,孟子"等url提取并访问,但在我们进去真正所需页面,例如"儒家"的次级目录中的"论语"时,编写的xpath才能提取到真正所需的内容,而其他页面获取为空。

截止目前,我们的思路是:先进入"先秦两汉"的页面,再访问"先秦两汉"目录下的所有url,随后在进入到例如:“论语”,"孟子"页面中的每一篇文章的url,这样即可拿到目标资源。

用个实例来理一理:
https://ctext.org/pre-qin-and-han/ens → https://ctext.org/analects/ens → https://ctext.org/analects/xue-er/ens
大致上是这样的顺序。

在访问页面的时候,我发现似乎并不是每一篇文章都有英文翻译,并且我还发现个别文章比我们预想的访问顺序会少一级,如图:

我们访问"独断"时,按照顺序显示的页面应该是"独断"目录下的每一篇文章的url,但这这里却直接显示出了目标内容,如图:

这是一个小坑,如果忽略这一点可能会导致我们爬取的数据不全,产生遗漏。所幸通过观察,我发现,带有中英文翻译的页面,在我们访问的第二级,也就是例如:"论语"的页面,"论语"页面中是其下每一篇文章的url,如果该篇文章内含中英文翻译,那该篇文章的url的标题结构就是 中文 + “-” + “英文”,而不带有英文翻译的 标题结构仅是 中文。如图:




似乎逻辑思路已经完善了,但在我编写代码完后发现中英文的数量对不上,中文会比英文的数量要多,这让我非常难受,在仔细排查一番后我发现,问题是出在最后的目标页面上,如图:



我们发现,如图上这个作为例子,安装思路,我们先进入 https://ctext.org/pre-qin-and-han/ens,然后进入 https://ctext.org/mozi/ens,而在墨子的页面中,其图示路径也不同,如图:

若是点箭头所指的url,一般是如图下所示的页面:

但"墨子"的"卷十一"却不同,如图:


"卷十一"的内容不是次级url而是目标文本,并且其文本中英文并不是一一对应。这个网站的页面属实有点乱,不过好在确定了思路,下面是代码部分。

二、代码部分

代码如下(示例):

import scrapy
from redis import Redis
from lxml.html import etree
from html import unescape
from scrapy import cmdline, selector, Requestclass ClassicalSpider(scrapy.Spider):name = 'classical'start_urls = ['https://ctext.org/pre-qin-and-han/ens','https://ctext.org/post-han/ens']conn = Redis(host='127.0.0.1', encoding='utf-8', port=6379)def parse(self, response):url_primary = response.xpath('//*[@id="content3"]/a/@href').getall()for i in url_primary:yield response.follow(url=i, callback=self.parse_detail,dont_filter=True)def parse_detail(self, response):b = response.bodypage = etree.HTML(b)page = unescape(page)whole_url = []whole_title = []Available_url = []Available_title = []content_chs_list = []content_ens_list = []for bad in page.xpath('//*[@id="content3"]/table[@border="0"]//td[@class="etext"]/p'):bad.getparent().remove(bad)for y in page.xpath('//table[@border="0"]'):content_chs = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="ctext"]') ifx.xpath('string(.)').strip()]content_ens = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="etext"]') ifx.xpath('string(.)').strip()]if len(content_chs) == len(content_ens):for i in content_chs:content_chs_list.append(i.strip())for i in content_ens:content_ens_list.append(i.strip())content_secondary = response.xpath('//*[@id="content2"]/a/@href').extract()for i in content_secondary:whole_url.append(i)title_primary = response.xpath('//*[@id="content2"]/a/text()').getall()for i in title_primary:whole_title.append(i)for whole_title,whole_url in zip(whole_title,whole_url):if whole_title.find('-')>=0:Available_url.append(whole_url)Available_title.append(whole_title)for ture_url in Available_url:yield response.follow(url=ture_url, callback=self.parse_page,meta={'chs': content_chs_list,'ens':content_ens_list})def parse_page(self, response):content = response.bodypage = etree.HTML(content)page = unescape(page)content_chs_list = response.meta['chs']content_ens_list = response.meta['ens']for bad in page.xpath('//*[@id="content3"]/table[@border="0"]//td[@class="etext"]/p'):bad.getparent().remove(bad)for y in page.xpath('//table[@border="0"]'):content_chs = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="ctext"]') ifx.xpath('string(.)').strip()]content_ens = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="etext"]') ifx.xpath('string(.)').strip()]if len(content_chs) == len(content_ens):for i in content_chs:content_chs_list.append(i.strip())for i in content_ens:content_ens_list.append(i.strip())if len(content_chs_list)==len(content_ens_list):ch_url = (response.url).replace('/ens','')yield response.follow(url=ch_url, callback=self.parse_ch,meta={'chs': content_chs_list,'ens':content_ens_list})def parse_ch(self, response):item = {}content_chs_list = response.meta['chs']content_ens_list = response.meta['ens']content = response.bodypage = etree.HTML(content)page = unescape(page)content_ch_list = []for bad in page.xpath('//*[@id="content3"]/table[@border="0"]//td[@class="etext"]/p'):bad.getparent().remove(bad)for y in page.xpath('//table[@border="0"]'):content_ch = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="ctext"]') ifx.xpath('string(.)').strip()]content_ens = [x.xpath('string(.)').strip() for x in y.xpath('.//td[@class="etext"]') ifx.xpath('string(.)').strip()]if len(content_ch) == len(content_ens):for i in content_ch:content_ch_list.append(i.strip())# content_ch = [x.xpath('string(.)') for x in page.xpath('//*[@id="content3"]/table[@border="0"]//td[@class="ctext"]')]# for i in content_ch:#     if i.strip():#         content_ch_list.append(i.strip())if len(content_chs_list) == len(content_ens_list) == len(content_ch_list):for chs,ch,ens in zip(content_chs_list,content_ch_list,content_ens_list):item['chs'] = chsitem['ch'] = chitem['ens'] = ens# print(item)yield itemif __name__ == '__main__':cmdline.execute(["scrapy", "crawl", "classical"])

总结

在完成一个网站代码的编写的同时,多关注逻辑部分以及代码本身,即使是简单的网站,不同代码的执行效率等也是不同的,这正是我们需要学习进步的点。

Python 网络爬虫:Scrapy框架下爬虫的简单思路相关推荐

  1. python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

    python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录.用于个人爬虫学习记 ...

  2. python scrapy爬虫视频_python爬虫scrapy框架的梨视频案例解析

    之前我们使用lxml对梨视频网站中的视频进行了下载 下面我用scrapy框架对梨视频网站中的视频标题和视频页中对视频的描述进行爬取 分析:我们要爬取的内容并不在同一个页面,视频描述内容需要我们点开视频 ...

  3. Python爬虫 scrapy框架爬取某招聘网存入mongodb解析

    这篇文章主要介绍了Python爬虫 scrapy框架爬取某招聘网存入mongodb解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 创建项目 sc ...

  4. Python爬虫—Scrapy框架—Win10下载安装

    Python爬虫-Scrapy框架-Win10下载安装 1. 下载wheel 2.下载twisted 3. 下载pywin32 4. 下载安装Scrapy 5. 创建一个scrapy项目 6. fir ...

  5. Scrapy框架下的海贼王漫画自动爬虫

    从小就是个海贼迷,学了爬虫后第一个上手自己写的爬虫自然而然就想到了爬海贼的漫画. 是在scrapy框架下写的爬虫,至于scrapy框架的安装就不多说了,网上有很多的安装教程. 前提准备 进到放置文件的 ...

  6. python cookie池_Python爬虫scrapy框架Cookie池(微博Cookie池)的使用

    下载代码Cookie池(这里主要是微博登录,也可以自己配置置其他的站点网址) 下载代码GitHub:https://github.com/Python3WebSpider/CookiesPool 下载 ...

  7. scrapy框架下pythom爬虫的数据库(MYSQL)

    本次主要讲述在scrapy框架下pythom爬虫有关mysql数据库的相关内容. 首先在MySQL数据库中创建对应的表,注意字段的设计! 数据库的信息存在setting 里,数据信息host,data ...

  8. Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider

    Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider 写在前面 初探Crawl Spider 创建Crawl Spider项目 对比Basic与Crawl ...

  9. 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案

    关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 参考文章: (1)关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 (2)https://www. ...

  10. 爬虫Scrapy框架运用----房天下二手房数据采集

    在许多电商和互联网金融的公司为了更好地服务用户,他们需要爬虫工程师对用户的行为数据进行搜集.分析和整合,为人们的行为选择提供更多的参考依据,去服务于人们的行为方式,甚至影响人们的生活方式.我们的scr ...

最新文章

  1. 神经网络中的权重初始化一览:从基础到Kaiming
  2. 春愁(shunshu)—Mrs. Green Apple (歌词、汉译、罗马音)
  3. 深入Windows原理杂记
  4. C语言经典例85-判断一个素数能被几个9整除
  5. idea 自定义工具栏
  6. keras笔记-模型保存以及tensorboard的使用
  7. nginx PHP执行 502 bad gateway 或空白解决笔记
  8. 光纤光信号闪红灯_光纤猫光信号闪红灯
  9. 使用localstorage及js模版引擎 开发 m站设想
  10. 计算机编程 设计入门,计算机编程入门图文教程_计算机程序设计教程,计算机编程入门教程-其它文档类资源...
  11. 如何配置mysql_怎样配置MySQL
  12. Cterm里面自动发帖的Python脚本
  13. “1+7+N”改革工作体系介绍
  14. arcgis 循环模型批量处理_科学网-ArcGIS模型构建器批处理操作-张凌的博文
  15. 如何获取和发现用户需求
  16. tyvj 1463 智商问题
  17. 物流matlab,物流配送线路优化Matlab算法研究
  18. C语言:判断一个数是否为素数/质数
  19. HTML二级下拉菜单常见样式以及常见问题
  20. 系统集成项目管理工程师10大管理47个过程域输入输出工具(项目范围管理)

热门文章

  1. java中下标和标识符_如下哪个是 Java 中的标识符 ( )_学小易找答案
  2. angular对象简单介绍
  3. 什么是驻点和拐点_驻点、极值点、拐点、鞍点的区别与联系
  4. hdmi接口线_视频接口与视频线详解!
  5. html添加好友界面,添加好友.html
  6. 使用管理员权限强制删除文件夹
  7. 中国移动的呼叫转移呼叫等待等设置方法 USSD MMI
  8. SU(seismic unix)常用操作001——sgy文件与su文件的相互转化
  9. Fedora14源代码获取方法----直接到官网去下载
  10. 人人车北京第二家严选店开业 称年内将覆盖一二线城市