Python爬虫总结

总的来说,Python爬虫所做的事情分为两个部分,1:将网页的内容全部抓取下来,2:对抓取到的内容和进行解析,得到我们需要的信息。

目前公认比较好用的爬虫框架为Scrapy,而且直接使用框架比自己使用requests、 beautifulsoup、 re包编写爬虫更加方便简单。

1、关于Scrapy框架

简介: Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

官方文档地址 : http://scrapy-chs.readthedocs.io/zh_CN/1.0/index.html

Scrapy安装 :  pip install Scrapy

创建Scrapy项目 : scrapy startproject scrapyspider(projectname)

该命令创建包涵下列内容的目录:

这些文件分别是:

  • scrapy.cfg: 项目的配置文件。
  • scrapyspider/: 该项目的python模块。之后您将在此加入代码。
  • scrapyspider/items.py: 项目中的item文件。
  • scrapyspider/pipelines.py: 项目中的pipelines文件,用来执行保存数据的操作。
  • scrapyspider/settings.py: 项目的设置文件。
  • scrapyspider/spiders/: 放置爬虫代码的目录。

 

  

 

 

 编写爬虫:以爬取豆瓣电影TOP250为例展示一个完整但简单的Scrapy爬虫的流程

  • 首先,在items.py文件中声明需要提取的数据,Item 对象是种简单的容器,保 存了爬取到得数据。 其提供了 类似于词典(dictionary-like) 的API以及用于声明可 用字段的简单语法。许多Scrapy组件使用了Item提供的额外信息: exporter根据 Item声明的字段来导出 数据、 序列化可以通过Item字段的元数据(metadata) 来 定义、trackref 追踪Item 实例来帮助寻找内存泄露 (see 使用 trackref 调试内 存泄露) 等等。
  • Item使用简单的class定义语法以及Field对象来声明。我们打开scrapyspider目录下的items.py文件写入下列代码声明Item:

为了创建一个爬虫,首先需要继承scrapy.Spider类,定义以下三个属性:

1、name : 用于区别不同的爬虫,名字必须是唯一的。

2、start_urls: 包含了Spider在启动时进行爬取的url列表。

3、parse() 是spider的一个函数。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数,然后解析提取数据。

在scrapyspider/spiders目录下创建douban_spider.py文件,并写入初步的代码:

from scrapy import Request

from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanMovieTop250Spider(Spider):

name = 'douban_movie_top250'

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',}#设置请求头文件,模拟浏览器访问(涉及反爬机制)

def start_requests(self):#该函数定义需要爬取的初始链接并下载网页内容

url = 'https://movie.douban.com/top250'

yield Request(url, headers=self.headers)

def parse(self, response):

item = DoubanMovieItem()

movies = response.xpath('//ol[@class="grid_view"]/li') #使用xpath对下载到的网页源码进行解析

for movie in movies:

item['ranking'] = movie.xpath(

'.//div[@class="pic"]/em/text()').extract()[0]

item['movie_name'] = movie.xpath(

'.//div[@class="hd"]/a/span[1]/text()').extract()[0]

item['score'] = movie.xpath(

'.//div[@class="star"]/span[@class="rating_num"]/text()'

).extract()[0]

item['score_num'] = movie.xpath(

'.//div[@class="star"]/span/text()').re(ur'(\d+)人评价')[0]

yield item

next_url =  response.xpath('//span[@class="next"]/a/@href').extract() #解析得到下一页的链接

if next_url:

next_url = 'https://movie.douban.com/top250' + next_url[0]

yield Request(next_url, headers=self.headers) #下载下一页的网页内容

 

运行爬虫: 在项目文件夹内打开cmd运行下列命令:

 

此处的douban_movie_top250即为我们刚刚写的爬虫的name, 而-o douban.csv是scrapy提供的功能,将item输出为csv格式的文件,存储到douban.csv中。

得到数据:

到此我们已经可以解决一般普通网站的抓取任务,普通网站是指网页源码之中包含了所有我们想要抓取的内容,但是有的时候一些网站采用了Ajax异步加载的方法,导致以上介绍的方法无法使用。

2、关于抓取Ajax异步加载的网站

 

Ajax是什么:

 

AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

通过Ajax异步加载的网页内容在网页源码中是没有的,也就是之前介绍的方法中下载到的response中是解析不到我们想要的内容的。

如何抓取AJAX异步加载页面

对于这类网页,我们一般采用两种方法:

1、通过抓包找到异步加载请求的真正地址

2、通过PhantomJS等无头浏览器执行JS代码后再抓取

但是通常采取第一种方法,因为第二种方法使用无头浏览器会大大降低抓取的效率。

异步加载网站抓取示例 :

使用豆瓣电影分类排行榜作为抓取示例,链接为

https://movie.douban.com/typerank?type_name=%E5%8A%A8%E4%BD%9C&type=5&interval_id=100:90&action=

电影信息网页源码中没有,并且采用鼠标下拉更新页面,这时需要我们在需要抓取的页面打开Chrome的开发者工具,选择network,实现一次下拉刷新

发现新增了一个get请求,并且响应为JSON格式。观察JSON的内容,发现正是需要抓取的内容。

抓取内容的问题解决了,接下来处理多页抓取问题,因为请求为get形式,所以首先进行几次下拉刷新,观察请求链接的变化,会发现请求的地址中只有start的值在变化,并且每次刷新增加20,其他都不变,所以我们更改这个参数就可以实现翻页。

由于之前已经在items.py中对需要抓取的数据做了声明,所以只需要在scraoyspider/spiders目录下创建一个新的爬虫文件douban_actions.py,代码如下:

import re

import json

from scrapy import Request

from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanAJAXSpider(Spider):

name = 'douban_ajax' #设置爬虫名字为douban_ajax

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',

} #设置请求头文件,模拟浏览器访问(涉及反爬机制)

def start_requests(self):

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start =0&limit=20'

yield Request(url, headers=self.headers)

def parse(self, response):

datas = json.loads(response.body)#将Json格式数据处理为字典类型

item = DoubanMovieItem()

if datas:

for data in datas:

item['ranking'] = data['rank']

item['movie_name'] = data['title']

item['score'] = data['score']

item['score_num'] = data['vote_count']

yield item

# 如果datas存在数据则对下一页进行采集

page_num = re.search(r'start=(\d+)', response.url).group(1)

page_num = 'start=' + str(int(page_num)+20)

next_url = re.sub(r'start=\d+', page_num, response.url)

    #处理链接

yield Request(next_url, headers=self.headers)

    #请求下一页

运行爬虫

  scrapy crawl douban_ajax -o douban_movie.csv

然而,很多时候ajax请求都会经过后端鉴权,不能直接构造URL获取。这时就可以通过PhantomJS、chromedriver等配合Selenium模拟浏览器动作,抓取经过js渲染后的页面。

使用这种方法有时会遇到定位网页页面元素定位不准的情况,这时就要注意网页中的frame标签,frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,需要进行frame的跳转。(这两点暂不展开,在抓取中财网—数据引擎网站时就遇到此类问题)

彩蛋

两个提高效率的Chrome插件:

  Toggle JavaScript  (检测网页哪些内容使用了异步加载)

  JSON-handle (格式化Json串)

 

3、关于突破爬虫反爬机制

 

   目前使用到的反反爬手段主要有三个:

1、在请求之间设置延时,限制请求速度。(使用python time库)

2、在每次请求时都随机使用用户代理User-Agent,为了方便,在scrapy框架中,可以使用fake-useragent这个开源库。

Github地址:https://github.com/hellysmile/fake-useragent

3、使用高匿代理ip,同样为了方便,在scrapy框架中编写爬虫,建议使用开源库 scrapy-proxies。

Github地址:https://github.com/aivarsk/scrapy-proxies

参考内容地址:https://zhuanlan.zhihu.com/p/24769534

关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案的更多相关文章

  1. 爬虫——爬取Ajax动态加载网页

    常见的反爬机制及处理方式 1.Headers反爬虫 :Cookie.Referer.User-Agent 解决方案: 通过F12获取headers,传给requests.get()方法 2.IP限制 ...

  2. Python网络爬虫_爬取Ajax动态加载和翻页时url不变的网页

    1 . 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新 ...

  3. 爬虫--selenuim和phantonJs处理网页动态加载数据的爬取

    1.谷歌浏览器的使用 下载谷歌浏览器 安装谷歌访问助手 终于用上谷歌浏览器了.....激动 问题:处理页面动态加载数据的爬取 -1.selenium -2.phantomJs 1.selenium 二 ...

  4. Ajax动态加载数据

    前言: 1.这个随笔实现了一个Ajax动态加载的例子. 2.使用.net 的MVC框架实现. 3.这个例子重点在前后台交互,其它略写. 开始: 1.控制器ActionResult代码(用于显示页面) ...

  5. 爬虫开发6.selenuim和phantonJs处理网页动态加载数据的爬取

    selenuim和phantonJs处理网页动态加载数据的爬取阅读量: 1203 动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材http://sc.chinaz.com/ ...

  6. 移动端,ajax 动态加载的元素,为动态添加的一系列同个类名的元素添加点击事件

    背景:一个列表页,有一系列同类名的元素,需要为每一个动态添加的列表项添加事件: 点击选择下图中不同的文档类型,再通过 ajax 动态加载不同的文档. 使用过的方法: 1.通知 jquery 的 $(s ...

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

    网络爬虫,是在网上进行数据抓取的程序,使用它能够抓取特定网页的HTML数据.虽然我们利用一些库开发一个爬虫程序,但是使用框架可以大大提高效率,缩短开发时间.Scrapy是一个使用Python编写的,轻 ...

  8. Python3 网络爬虫:漫画下载,动态加载、反爬虫这都不叫事

    一.前言 作者:Jack Cui 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那 ...

  9. AJAX 动态加载后台数据 绑定select

    <select id="select"> <!--下拉框数据动态加载--> </select> js:(使用jquery) $(document ...

随机推荐

  1. Java并发编程--线程池

    1.ThreadPoolExecutor类 java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,下面我们来看一下ThreadPoolExecuto ...

  2. 基于HTML5及WebGL的工控SCADA模拟飞机飞行

    昨天看到一篇文章说是学习如何开飞机的,然后我就想,如果我也可以开飞机那就好玩了,每个人小时候都想做飞行员!中国飞行员太难当了,再说也不轻易让你开飞机!后来我就想如果能用 HT 开飞机那就是真的有趣了, ...

  3. x86-64栈帧中的“红色区域” red zone of stack frame on x86-64

    前几天看System V AMD64 ABI标准的时候发现栈帧的顶部后面有一块"red zone",在学cs:app3e/深入理解操作系统的时候并没有遇到这个,总结一下. 引用标准 ...

  4. [转载]ACM搜索算法总结(总结)

    原文地址:ACM搜索算法总结(总结)作者:GreenHand 搜索是ACM竞赛中的常见算法,本文的主要内容就是分析它的 特点,以及在实际问题中如何合理的选择搜索方法,提高效率.文章的第一部分首先分析了 ...

  5. 交换知识 VLAN VTP STP 单臂路由

    第1章 交换基础 1.1 园区网分层结构 层次 作用 出口层 广域网接入 出口策略 带宽控制 核心层 高速转发 服务器接入 路由选择 汇聚层 流量汇聚 链路冗余 设备冗余 路由选择 接入层 用户接入 ...

  6. jsp静态与动态包含的区别和联系

    1. <%@ include file=” ”%>是指令元素.<jsp:include page=” ”/>是行为元素 2. 最终编译成java文件的数目不同. * 静态包含在 ...

  7. [eclipse相关] eclipse 安装svn插件

    最近看到别人带主题的eclipse,非常羡慕,所以也换了一个eclipse,版本是java ee luna 4.4.2,然后得偿所愿有了花花绿绿的代码界面:) 但是差点被svn搞死,~~~~(> ...

  8. 坦言spring中事务、重试、异步执行注解

    一.@Transaction 我们再编码过程中,大量使用到这个注解.一般情况下,@Transaction使用默认注解可以完成90%的功能,下面会针对一些特殊场景下,@Tansaction的使用注意 1 ...

  9. bzoj1001(对偶图最短路)

    显然是个最大流问题. 边数达到了10^6级别,显然用dinic算法会TLE 对于一个平面图来说,当然用对偶图的最短路来求最小割(最大流) SPFA转移的时候注意判断边界情况 应该要开longlong才 ...

  10. Maven元素解析——pom.xml

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6628201.html  一个pom.xml中包含了许多标签,各个标签是对项目生命周期.依赖管理的配置.常用的主 ...