资讯专栏INFORMATION COLUMN

爬虫学习之基于 Scrapy 的爬虫自动登录

Panda / 1549人阅读

摘要:概述在前面两篇爬虫学习之基于的网络爬虫和爬虫学习之简单的网络爬虫文章中我们通过两个实际的案例,采用不同的方式进行了内容提取。

概述

在前面两篇(爬虫学习之基于Scrapy的网络爬虫和爬虫学习之简单的网络爬虫)文章中我们通过两个实际的案例,采用不同的方式进行了内容提取。我们对网络爬虫有了一个比较初级的认识,只要发起请求获取响应的网页内容,然后对内容进行格式化存储。很多时候我们抓取到的内容可能会发生重复,也有可能是需要计算或者组织过的全新的内容甚至是需要登录后才能访问的内容, 那么这一篇我们来学习一下Scrapy的Item部分以及了解如何使用Scrapy来进行自动登录。

起步

首先我们使用Scrapy的命令行创建一个新的项目

</>复制代码

  1. scrapy startproject douban

运行后,我们就有了下面这样的目录结构

</>复制代码

  1. + douban # 根目录
  2. |- douban # Python的项目目录
  3. |- spiders # 爬虫Spider部分,用于提取网页内容
  4. |- __init__.py
  5. |- __init__.py
  6. |- items.py # 爬虫item, 用于定义数据结构
  7. |- pipelines.py # 爬虫pipeline,用于处理提取的结构,比如清洗数据、去重等
  8. |- settings.py # Scrapy框架参数项目参数设置
  9. |- scrapy.cfg # 爬虫部署相关设置

Scrapy为我们生成了已经组织好的目录结构,上面的注释部分解释了每个文件及目录的作用。

建立目标

本篇我们来建立两个目标,这两个目标都是基于豆瓣网:

目标一:抓取豆瓣TOP250的图书信息并保存成csv文件

目标二:抓取我的第一页豆邮标题(需要登录),并保存成csv文件

分析目标一

目标一是豆瓣的TOP250图书信息,首先我们进入到TOP250的列表(https://book.douban.com/top250) ,我用图示圈出我们这次要爬取的内容,具体请看图示:

从图上的框线中我们主要圈出了书名、价格、出版年份、出版社、评分,其中出版年份,出版社以及价格是在一行中,这个我们需要进一步处理。

分页的处理:总记录是250条,每页是25条图书信息,共分了10页。

实现目标一

需要用到的概念:

Item

Item Pipeline

首先建立Scrapy的Item, Scrapy的Item就是我们需要存储的数据结构,先修改items, 然后在spiders目录中新建一个名为bookspider.py的Python文件,由于我们需要在一堆字符串中提取出出版社和价格等信息所以我们这里需要对抓取的内容进一步处理, 在这之前还需要修改settings.py文件:

加入faker的模拟USER_AGENT数据防止被豆瓣屏蔽,

也可以设置DEFAULT_REQUEST_HEADERS参数。

修改ITEM_PIPELINES

代码如下所示:

items.py

</>复制代码

  1. # -*- coding: utf-8 -*-
  2. """by sudo rm -rf http://imchenkun.com"""
  3. import scrapy
  4. class DoubanBookItem(scrapy.Item):
  5. name = scrapy.Field() # 书名
  6. price = scrapy.Field() # 价格
  7. edition_year = scrapy.Field() # 出版年份
  8. publisher = scrapy.Field() # 出版社
  9. ratings = scrapy.Field() # 评分

bookspider.py

</>复制代码

  1. # -*- coding:utf-8 -*-
  2. """by sudo rm -rf http://imchenkun.com"""
  3. import scrapy
  4. from douban.items import DoubanBookItem
  5. class BookSpider(scrapy.Spider):
  6. name = "douban-book"
  7. allowed_domains = ["douban.com"]
  8. start_urls = [
  9. "https://book.douban.com/top250"
  10. ]
  11. def parse(self, response):
  12. # 请求第一页
  13. yield scrapy.Request(response.url, callback=self.parse_next)
  14. # 请求其它页
  15. for page in response.xpath("//div[@class="paginator"]/a"):
  16. link = page.xpath("@href").extract()[0]
  17. yield scrapy.Request(link, callback=self.parse_next)
  18. def parse_next(self, response):
  19. for item in response.xpath("//tr[@class="item"]"):
  20. book = DoubanBookItem()
  21. book["name"] = item.xpath("td[2]/div[1]/a/@title").extract()[0]
  22. book["price"] = item.xpath("td[2]/p/text()").extract()[0]
  23. book["ratings"] = item.xpath("td[2]/div[2]/span[2]/text()").extract()[0]
  24. yield book

pipelines.py

</>复制代码

  1. # -*- coding: utf-8 -*-
  2. """by sudo rm -rf http://imchenkun.com"""
  3. class DoubanBookPipeline(object):
  4. def process_item(self, item, spider):
  5. info = item["price"].split(" / ") # [法] 圣埃克苏佩里 / 马振聘 / 人民文学出版社 / 2003-8 / 22.00元
  6. item["name"] = item["name"]
  7. item["price"] = info[-1]
  8. item["edition_year"] = info[-2]
  9. item["publisher"] = info[-3]
  10. return item

最后我们到douban的根目录中执行以下命令来运行爬虫来执行并导出数据到csv文件

</>复制代码

  1. scrapy crawl douban-book -o douban_book_top250.csv

csv文件截图如下:

分析目标二

目标二是建立在理解了目标一的基础上进行的,因为豆瓣登录次数过多会有验证码出现,这里提供一种手工填写验证码的方式,暂时不讨论如何去识别验证码,目标二的核心概念是如何提交POST表单和登录成功后带Cookie的请求。首先我们可以看到页面结构如下图所示:

实现目标二

定义Item

</>复制代码

  1. # -*- coding: utf-8 -*-import scrapy
  2. """by sudo rm -rf http://imchenkun.com"""
  3. class DoubanMailItem(scrapy.Item):
  4. sender_time = scrapy.Field() # 发送时间
  5. sender_from = scrapy.Field() # 发送人
  6. url = scrapy.Field() # 豆邮详细地址
  7. title = scrapy.Field() # 豆邮标题

定义doumailspider

</>复制代码

  1. # -*- coding:utf-8 -*-
  2. """by sudo rm -rf http://imchenkun.com"""
  3. import scrapy
  4. from faker import Factory
  5. from douban.items import DoubanMailItem
  6. import urlparse
  7. f = Factory.create()
  8. class MailSpider(scrapy.Spider):
  9. name = "douban-mail"
  10. allowed_domains = ["accounts.douban.com", "douban.com"]
  11. start_urls = [
  12. "https://www.douban.com/"
  13. ]
  14. headers = {
  15. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  16. "Accept-Encoding": "gzip, deflate, br",
  17. "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
  18. "Connection": "keep-alive",
  19. "Host": "accounts.douban.com",
  20. "User-Agent": f.user_agent()
  21. }
  22. formdata = {
  23. "form_email": "您的账号",
  24. "form_password": "您的密码",
  25. # "captcha-solution": "",
  26. # "captcha-id": "",
  27. "login": "登录",
  28. "redir": "https://www.douban.com/",
  29. "source": "None"
  30. }
  31. def start_requests(self):
  32. return [scrapy.Request(url="https://www.douban.com/accounts/login",
  33. headers=self.headers,
  34. meta={"cookiejar": 1},
  35. callback=self.parse_login)]
  36. def parse_login(self, response):
  37. # 如果有验证码要人为处理
  38. if "captcha_image" in response.body:
  39. print "Copy the link:"
  40. link = response.xpath("//img[@class="captcha_image"]/@src").extract()[0]
  41. print link
  42. captcha_solution = raw_input("captcha-solution:")
  43. captcha_id = urlparse.parse_qs(urlparse.urlparse(link).query, True)["id"]
  44. self.formdata["captcha-solution"] = captcha_solution
  45. self.formdata["captcha-id"] = captcha_id
  46. return [scrapy.FormRequest.from_response(response,
  47. formdata=self.formdata,
  48. headers=self.headers,
  49. meta={"cookiejar": response.meta["cookiejar"]},
  50. callback=self.after_login
  51. )]
  52. def after_login(self, response):
  53. print response.status
  54. self.headers["Host"] = "www.douban.com"
  55. return scrapy.Request(url="https://www.douban.com/doumail/",
  56. meta={"cookiejar": response.meta["cookiejar"]},
  57. headers=self.headers,
  58. callback=self.parse_mail)
  59. def parse_mail(self, response):
  60. print response.status
  61. for item in response.xpath("//div[@class="doumail-list"]/ul/li"):
  62. mail = DoubanMailItem()
  63. mail["sender_time"] = item.xpath("div[2]/div/span[1]/text()").extract()[0]
  64. mail["sender_from"] = item.xpath("div[2]/div/span[2]/text()").extract()[0]
  65. mail["url"] = item.xpath("div[2]/p/a/@href").extract()[0]
  66. mail["title"] = item.xpath("div[2]/p/a/text()").extract()[0]
  67. print mail
  68. yield mail

这里需要注意的有三个地方:

第一个是meta中的cookiejar
Scrapy 通过使用 cookiejar Request meta key来支持单spider追踪多cookie session。默认情况下其使用一个cookie jar(session),不过您可以传递一个标示符来使用多个。

start_requests 我们这里重写了爬虫爬取得第一个页面,这里一开始就进去到登录页面

当执行爬虫的时候,我们需要把打印出来的验证码地址粘贴到浏览器中,手动输入到控制上完成验证。

同目标一一样需要设置settings中的相关参数,唯一不同的是ITEM_PIPELINES。

最后我们使用以下命令来启动爬虫

</>复制代码

  1. scrapy crawl douban-mail -o douban_mail_page1.csv

csv文件截图如下:

Github地址:https://github.com/imchenkun/ick-spider/tree/master/douban

总结

本篇我们学习了如果定义Item以及如何对Item进行进一步处理(Item Pipeline), 还通过登录豆瓣的案例来了解了如果使用Scrapy进行表单提交和Cookie追踪,也了解了对于有验证码的情况该如何处理,当然我们这里暂时还不讨论如何识别验证码。关于Scrapy的更高级的一些用法和特性可以进一步阅读Scrapy官网的文档。

特别申明:本文所提到的豆瓣网只是拿来进行爬虫的技术交流学习,读者涉及到的所有侵权问题都与本人无关,也希望大家在学习实战的过程中不要大量的爬取内容对服务器造成负担

本文首发在sudo rm -rf 采用署名(BY)-非商业性使用(NC)-禁止演绎(ND) 转载请注明原作者

--EOF--

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38070.html

相关文章

  • 爬虫习之基于Scrapy网络爬虫

    摘要:不过不用担心,中有很多非常优秀的爬虫框架,比如我们接下来要学习到的。结合以上分析我们基本确定了本次爬虫的各个路线入口,接下来我们就开始通过程序来实现本次的目标。这里我们的目的是建立一种写爬虫的思路,而不在于怎么使用工具来爬数据。 概述 在上一篇文章《爬虫学习之一个简单的网络爬虫》中我们对爬虫的概念有了一个初步的认识,并且通过Python的一些第三方库很方便的提取了我们想要的内容,但是...

    BingqiChen 评论0 收藏0
  • 首次公开,整理12年积累博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • 零基础如何爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0
  • 爬虫爬 JSON HTML 数据

    摘要:最近这两周在忙着给公司爬一点数据,更文的速度有一点下降,预计今天就爬完了,总结总结经验。一个爬虫的框架。基本等价于选择其中的文字提取属性文档,这个我不会,我也没看使用这个类库解析如请求方式可以用来给中文字符数据放入传递即可。 最近这两周在忙着给公司爬一点数据,更文的速度有一点下降,预计今天就爬完了,总结总结经验。 其实之前我司是有专门做爬虫的,不用前端这边出人干活。后来那人离职了,有可...

    Hegel_Gu 评论0 收藏0
  • 爬虫爬 JSON HTML 数据

    摘要:最近这两周在忙着给公司爬一点数据,更文的速度有一点下降,预计今天就爬完了,总结总结经验。一个爬虫的框架。基本等价于选择其中的文字提取属性文档,这个我不会,我也没看使用这个类库解析如请求方式可以用来给中文字符数据放入传递即可。 最近这两周在忙着给公司爬一点数据,更文的速度有一点下降,预计今天就爬完了,总结总结经验。 其实之前我司是有专门做爬虫的,不用前端这边出人干活。后来那人离职了,有可...

    cocopeak 评论0 收藏0

发表评论

0条评论

Panda

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<