
c爬虫抓取网页数据
c爬虫抓取网页数据正常情况下发生的场景是什么?
网站优化 • 优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2022-09-06 16:02
c爬虫抓取网页数据正常情况下发生的场景是:用户发起一次请求,从浏览器的user-agent(浏览器上面一个host或者cookie)里面获取对应的body,然后交给爬虫解析交给c段发起连接请求,两边继续一对一的发起请求,但是一般情况下连接建立得不是太多,所以一般来说单方面只能发起一次连接请求。但是,机器比较多的情况下,系统可能就要发起一次连接请求了,比如加入了多种进程,那么这个连接请求可能连接多个进程,甚至数十个进程,在本文中,我们以一个前端每秒发起三次连接请求为例,将爬虫和后端连接请求相连接原理一次连接请求解析图解1:从user-agent我们知道用户浏览器里面的user-agent,浏览器在接收到了连接请求之后,首先会首先去查看请求里面的参数,看这些参数指定的资源是不是自己想要的,一般的发送的时候都会带着对应的headers,比如cookie之类的。
那么连接请求用到了哪些参数?user-agent:你要发送的user-agent-agent-名:你想发送的user-agent-agent-数:你想发送的user-agent-agent-cookie:你发送的user-agent-agent-数值那么requestheaders就是我们最常用的两个参数,头部的部分跟request没什么区别,这里重点看一下服务端参数第一个参数是cookie,前面请求里面也提到了,这个cookie在别的连接请求里面可能会用到;其次还有一个cookiebanner,也就是获取cookie的通道,一般来说可以用httpcookie连接推送http请求推送完cookie之后,后面这些数据就不再重复发送了。
第二个是服务端可以获取到的参数还有:cookie的host和max-age设置你的端口及子域名之类的对第一个参数进行检查,如果是一个比较熟悉自己程序请求的人,他会知道使用自己家的服务器,或者是自己家的机器,或者是自己家机器的内部连接,实际上你还可以在后台找到一些端口。对第二个参数,我们一般也是根据自己的业务来选择对应的参数,如果要抓的数据量大,我们的连接请求数可能就会很多,或者对user-agent提供了头部的cookie可以直接在相应设置连接请求,如果需要抓多个不同资源,在不太熟悉的情况下,最好就抓取一个,进行连接请求,这样可以减轻连接请求的负担,而使得连接效率更高。
2:给请求加上代理如果要发送多个user-agent请求,那么一个个的发送这种连接请求会很慢的,那么可以加一个代理服务器进行发送,代理服务器可以是公网的,也可以是爬虫自己的机器,速度比在本地发送要快,而且,代理服务器里面数据也是你自己配置的,这样可以防止恶意爬虫连接请求到你的程序。那么。 查看全部
c爬虫抓取网页数据正常情况下发生的场景是什么?
c爬虫抓取网页数据正常情况下发生的场景是:用户发起一次请求,从浏览器的user-agent(浏览器上面一个host或者cookie)里面获取对应的body,然后交给爬虫解析交给c段发起连接请求,两边继续一对一的发起请求,但是一般情况下连接建立得不是太多,所以一般来说单方面只能发起一次连接请求。但是,机器比较多的情况下,系统可能就要发起一次连接请求了,比如加入了多种进程,那么这个连接请求可能连接多个进程,甚至数十个进程,在本文中,我们以一个前端每秒发起三次连接请求为例,将爬虫和后端连接请求相连接原理一次连接请求解析图解1:从user-agent我们知道用户浏览器里面的user-agent,浏览器在接收到了连接请求之后,首先会首先去查看请求里面的参数,看这些参数指定的资源是不是自己想要的,一般的发送的时候都会带着对应的headers,比如cookie之类的。

那么连接请求用到了哪些参数?user-agent:你要发送的user-agent-agent-名:你想发送的user-agent-agent-数:你想发送的user-agent-agent-cookie:你发送的user-agent-agent-数值那么requestheaders就是我们最常用的两个参数,头部的部分跟request没什么区别,这里重点看一下服务端参数第一个参数是cookie,前面请求里面也提到了,这个cookie在别的连接请求里面可能会用到;其次还有一个cookiebanner,也就是获取cookie的通道,一般来说可以用httpcookie连接推送http请求推送完cookie之后,后面这些数据就不再重复发送了。

第二个是服务端可以获取到的参数还有:cookie的host和max-age设置你的端口及子域名之类的对第一个参数进行检查,如果是一个比较熟悉自己程序请求的人,他会知道使用自己家的服务器,或者是自己家的机器,或者是自己家机器的内部连接,实际上你还可以在后台找到一些端口。对第二个参数,我们一般也是根据自己的业务来选择对应的参数,如果要抓的数据量大,我们的连接请求数可能就会很多,或者对user-agent提供了头部的cookie可以直接在相应设置连接请求,如果需要抓多个不同资源,在不太熟悉的情况下,最好就抓取一个,进行连接请求,这样可以减轻连接请求的负担,而使得连接效率更高。
2:给请求加上代理如果要发送多个user-agent请求,那么一个个的发送这种连接请求会很慢的,那么可以加一个代理服务器进行发送,代理服务器可以是公网的,也可以是爬虫自己的机器,速度比在本地发送要快,而且,代理服务器里面数据也是你自己配置的,这样可以防止恶意爬虫连接请求到你的程序。那么。
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长
网站优化 • 优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2022-08-28 03:09
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长,节省了很多计算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要实现不同url间的切换时候需要session,并且每个spider的不同url解析采用不同的spiderspider所以三者实现逻辑差异不大以下代码是在scrapy框架下实现的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目录和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome浏览器命令fromin(url)fromax(url)#定位浏览器输入url时候的错误drivermanager(x。 查看全部
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长

c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长,节省了很多计算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要实现不同url间的切换时候需要session,并且每个spider的不同url解析采用不同的spiderspider所以三者实现逻辑差异不大以下代码是在scrapy框架下实现的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目录和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome浏览器命令fromin(url)fromax(url)#定位浏览器输入url时候的错误drivermanager(x。
网络爬虫入门之python
网站优化 • 优采云 发表了文章 • 0 个评论 • 77 次浏览 • 2022-08-09 02:18
网络爬虫定义:
(来自于百度百科):网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
为什么要学:
在数据爆发式增长时代,如果这些数据得以分析利用,可以帮助企业更好的做出决策。网络爬虫技术,也是大数据分析的第一个环节。
Robots协议(爬虫协议)
全称是网络爬虫排除标准,通过该协议告诉搜索引擎哪些页面可以抓取,哪些不能抓取。是国际互联网通行的道德规范,虽然没有写入法律,但每一个爬虫都应该遵守这项协议。
python
(来自于百度百科):Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。
2021年10月,语言流行指数的编译器Tiobe将Python加冕为最受欢迎的编程语言,20年来首次将其置于Java、C和JavaScript之上。
版本很多,本次使用python3
python爬虫流程
重要知识点:
获取网页:requests、urllib、selenium
解析网页:re正则表达式、BeautifulSoup、lxml
存储数据:存入txt、csv、存入mysql、redis、mongodb等
框架:scrapy
python 安装
使用Anaconda科学计算环境下载python
安装步骤 自行搜索百度,有很多,其实就是下一步下一步。使用pip安装第三方库或者使用Anaconda安装第三方库。
编辑器:Pycharm
如果你使用Python安装包下载的python,推荐使用pycharm编辑器。下载免费版即可,官网好像被墙了。
python之初尝试
python之爬虫初尝试 查看全部
网络爬虫入门之python
网络爬虫定义:
(来自于百度百科):网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
为什么要学:
在数据爆发式增长时代,如果这些数据得以分析利用,可以帮助企业更好的做出决策。网络爬虫技术,也是大数据分析的第一个环节。
Robots协议(爬虫协议)
全称是网络爬虫排除标准,通过该协议告诉搜索引擎哪些页面可以抓取,哪些不能抓取。是国际互联网通行的道德规范,虽然没有写入法律,但每一个爬虫都应该遵守这项协议。
python
(来自于百度百科):Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。
2021年10月,语言流行指数的编译器Tiobe将Python加冕为最受欢迎的编程语言,20年来首次将其置于Java、C和JavaScript之上。

版本很多,本次使用python3
python爬虫流程
重要知识点:
获取网页:requests、urllib、selenium
解析网页:re正则表达式、BeautifulSoup、lxml
存储数据:存入txt、csv、存入mysql、redis、mongodb等
框架:scrapy
python 安装
使用Anaconda科学计算环境下载python
安装步骤 自行搜索百度,有很多,其实就是下一步下一步。使用pip安装第三方库或者使用Anaconda安装第三方库。

编辑器:Pycharm
如果你使用Python安装包下载的python,推荐使用pycharm编辑器。下载免费版即可,官网好像被墙了。
python之初尝试
python之爬虫初尝试
c爬虫抓取网页数据,比如百度全部关键词爬虫。
网站优化 • 优采云 发表了文章 • 0 个评论 • 108 次浏览 • 2022-08-05 14:05
c爬虫抓取网页数据,比如百度全部关键词爬虫。update2:20190913又看了一下,问题中是纯元数据。本身元数据没有地域归属。这样设置,useragent提供的信息仅限于ip和mac地址,而你能爬取的并不是这些信息。你需要axios+request来注册scrapy,才能爬取以外的信息。以下为20190710补充:github上有提供examples:examples|scrapy学习。
nlp方面,有一些国内论坛可以去学习。比如,通过python的poc文本识别正则表达式(抓取百度网页上的文本信息,并翻译英文,但非微信的文章信息)。
如果你是零基础的话,推荐去csdn看看一个和你问题有相似需求的人在使用什么框架和数据库。web的话,爬虫爬取评论数据用前端selenium。找相关的网站翻译一下。如果可以看懂的话可以试着写一个爬虫这样。我目前是这么干的,具体不太懂。感觉时间比较紧,
回答你的问题首先要说明的是,市面上比较多,国内的,国外的,mongodb等等很多,我只知道其中的一款,如果你想学习爬虫的话,建议去学习一下,因为爬虫要对各种兼容性进行分析,可能你需要写几个框架,从最开始的caffe到其他的,从此要自己写框架,初学的话,这些框架你可以选择一个,其实安卓,ios都可以搭建自己的网站,反正不都是web吗,所以你也可以去学习一下。
并不是不会,是因为没经历过,作为初学者,建议还是先学一些框架,比如requests+xpath+beautifulsoup4(因为本人java基础不是很好,所以选择了前三个,做练习可以选择其他的)lxmlpyquery等等或者直接学一下flaskpyramid都可以。自己先去学一下其他的,然后了解一下api,通过各种api写一个网站,网站出来以后在选择一个框架,这样一来,一切都会水到渠成。 查看全部
c爬虫抓取网页数据,比如百度全部关键词爬虫。
c爬虫抓取网页数据,比如百度全部关键词爬虫。update2:20190913又看了一下,问题中是纯元数据。本身元数据没有地域归属。这样设置,useragent提供的信息仅限于ip和mac地址,而你能爬取的并不是这些信息。你需要axios+request来注册scrapy,才能爬取以外的信息。以下为20190710补充:github上有提供examples:examples|scrapy学习。

nlp方面,有一些国内论坛可以去学习。比如,通过python的poc文本识别正则表达式(抓取百度网页上的文本信息,并翻译英文,但非微信的文章信息)。
如果你是零基础的话,推荐去csdn看看一个和你问题有相似需求的人在使用什么框架和数据库。web的话,爬虫爬取评论数据用前端selenium。找相关的网站翻译一下。如果可以看懂的话可以试着写一个爬虫这样。我目前是这么干的,具体不太懂。感觉时间比较紧,

回答你的问题首先要说明的是,市面上比较多,国内的,国外的,mongodb等等很多,我只知道其中的一款,如果你想学习爬虫的话,建议去学习一下,因为爬虫要对各种兼容性进行分析,可能你需要写几个框架,从最开始的caffe到其他的,从此要自己写框架,初学的话,这些框架你可以选择一个,其实安卓,ios都可以搭建自己的网站,反正不都是web吗,所以你也可以去学习一下。
并不是不会,是因为没经历过,作为初学者,建议还是先学一些框架,比如requests+xpath+beautifulsoup4(因为本人java基础不是很好,所以选择了前三个,做练习可以选择其他的)lxmlpyquery等等或者直接学一下flaskpyramid都可以。自己先去学一下其他的,然后了解一下api,通过各种api写一个网站,网站出来以后在选择一个框架,这样一来,一切都会水到渠成。
c爬虫抓取网页数据更新的步骤是什么?怎么做
网站优化 • 优采云 发表了文章 • 0 个评论 • 291 次浏览 • 2022-06-29 07:02
c爬虫抓取网页数据更新的步骤:1.首先是获取目标网页的数据的方法,即获取这个网页所需要的数据。2.再是打包成数据包,下载到本地。然后对下载下来的数据做分析计算。有了本地的数据包,才能通过脚本更新网页。3.网页的更新即是用人工手动的方式取得网页最新的数据。这个过程需要使用抓包工具。4.http请求的代码以https格式写在代码最后。5.有人会问,这个代码在哪里?运行代码的时候,会用到浏览器开发者工具。
做爬虫的时候经常会用到一些爬虫工具,
可以使用多线程抓取,
我个人认为,
有个叫说手机app的那哥们,整天干这个。
曾经做过一段android全开源爬虫,可以爬lbs相关,更新比较及时,速度可以达到1000+,现在想想那是多年前的事了。
如果只爬公开数据(包括大数据),可以通过反爬虫机制。在androidapi409范围之内,比如:大商家之间的投票、大的赛事、大型论坛。在recaptcha加密机制之内,拿到中间地址。然后:翻墙找数据。(外国网站监控比较牛逼)在上一条的基础上,自己编写getheader或者cookie对爬虫,这个可以crawl,不过有点坑。
在自己程序中使用第三方爬虫,会和代理广告相关,自己肯定清楚相关的东西。或者agentdetector来监控哪个浏览器加速。有实力做爬虫网站比如一些专门做分析数据爬虫之类的东西,就是收费的东西,多爬一些数据吧。 查看全部
c爬虫抓取网页数据更新的步骤是什么?怎么做
c爬虫抓取网页数据更新的步骤:1.首先是获取目标网页的数据的方法,即获取这个网页所需要的数据。2.再是打包成数据包,下载到本地。然后对下载下来的数据做分析计算。有了本地的数据包,才能通过脚本更新网页。3.网页的更新即是用人工手动的方式取得网页最新的数据。这个过程需要使用抓包工具。4.http请求的代码以https格式写在代码最后。5.有人会问,这个代码在哪里?运行代码的时候,会用到浏览器开发者工具。
做爬虫的时候经常会用到一些爬虫工具,

可以使用多线程抓取,
我个人认为,
有个叫说手机app的那哥们,整天干这个。

曾经做过一段android全开源爬虫,可以爬lbs相关,更新比较及时,速度可以达到1000+,现在想想那是多年前的事了。
如果只爬公开数据(包括大数据),可以通过反爬虫机制。在androidapi409范围之内,比如:大商家之间的投票、大的赛事、大型论坛。在recaptcha加密机制之内,拿到中间地址。然后:翻墙找数据。(外国网站监控比较牛逼)在上一条的基础上,自己编写getheader或者cookie对爬虫,这个可以crawl,不过有点坑。
在自己程序中使用第三方爬虫,会和代理广告相关,自己肯定清楚相关的东西。或者agentdetector来监控哪个浏览器加速。有实力做爬虫网站比如一些专门做分析数据爬虫之类的东西,就是收费的东西,多爬一些数据吧。
数据分析|爬虫抓取东方财富网股吧帖子
网站优化 • 优采云 发表了文章 • 0 个评论 • 80 次浏览 • 2022-06-24 23:39
1前言
量化交易策略的研究主要涵盖了微观和宏观这两个方面,微观方面更多地是从市场价格和成交持仓这些基础信息为研究对象,通过算法计算出技术指标,再从技术指标的变化上构建交易模型。宏观方面则是基于更多的市场资讯开发交易模型,比如从CPI、PPI、货币发行量这些宏观经济指标为研究对象构建交易模型;或者是利用数据挖掘技术从新闻事件中挖掘出可能造成市场异常波动的事件,从而获得交易的时机。
我们知道知名股票论坛有点金投资家园、股天下、东方财富网股吧、和讯股吧、创幻论坛、MACD股市等等,笔者用的比较多的是东方财富网股吧。在课程《构建基于股票的量化交易系统》中我们以爬取东方财富网行业板块当日的行情数据为案例,介绍了网络爬虫的原理和方法,本节我们再介绍下如何爬取东方财富网股吧帖子的内容。
2
解析股吧帖子URL
首先通过浏览器访问伟星新材的股吧,查看该网页的URL为:
,002372.html,网页内容如下图所示:
当我们点击第2页、第3页后,查看下当前的URL分别为:
http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
因此得到了个股股吧URL的规律为:
, 002372_%d.html形式表示,
其中的规律比较直白,%d为论坛第几页,不过这个形式是按评论时间排列的网址,如果按发帖时间的排列网址是:
,002372,f_%d.html。
股吧的帖子由两部分组成,一部分为“财经评论”或“东方财富网”发布的公告或官方消息,另一部分为散户发布的讨论帖子,如下图所示:
前者的帖子URL为:
,cjpl,902659513.html,
后者的帖子URL为:
,002372,902629178.html
两者的URL都可在当前该股股吧HTML文件内容中搜寻到,如下所示:
因此“财经评论”、“东方财富网”或者散户发布的帖子,主要的特征为/news,在实现上我们可以先爬取到股吧HTML内容,然后通过正则表达式来筛选得到帖子的URL。
关于读取网页HTML内容的关键代码我们已经在课程《爬虫方式获取行业板块数据》一节中具体介绍过。需要注意的是Python2的urllib、urllib2和urlparse,已经在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的内容整合为urllib.request模块,urlparse整合为urllib.parse模块。
获取到HTML代码部分内容如下:
正则表达式筛选帖子URL,采用了pile和re.findall,实现代码如下:
其中正则表达式的\S+表示匹配多次非空白字符,然后使用findall函数找到匹配的所有字符串,并把它们作为一个列表返回。
然后是使用urljoin方法把整个url拼接好用于爬取单个帖子的标题内容,关键代码如下所示:
3创建爬虫URL队列
接下来我们把所有需要爬取的股吧页以及每页中的帖子的URL以队列的方式进行管理。Python中存储序列的类型有list、tuple、dict和set,它们之间的区别和特点简单的说:tuple不能修改其中的元素;set是无序集合,会自动去除重复元素;list是有序的集合;dict是一组key和value的组合。此次我们选择list作为队列的存储类型。
创建target_url_manager类,该类包含以下几个方法:
创建队列形式如下所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
4
解析股吧帖子内容
单个帖子爬取的内容包括三部分,帖子发表时间、作者及帖子标题,如下所示:
我们可以通过正则表达式进行提取,其中在组合正则表达式时,需要考虑到HTML代码中是否有重复的匹配关键字。作者和帖子标题正则代码如下,mainbody、zwcontentmain这些关键字在文本中仅出现一次,匹配程度较高。由于网站HTML代码的改动,表达式需要经常调整。
关键代码如下所示:
com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
发布时间正则代码如下,分两步逐渐明晰的去提取时间,由于search是扫描字符串找到这个RE 匹配的位置,因此增加group()返回匹配字符串。
pub_elems = re.search('.*?',html_cont2).group()#发表于 2020-02-11 09:54:48 东方财富Android版<br />pub_time = re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
<br />
另外,论坛帖子与当前的股价走势有时间联系,太早的帖子对现在无参考作用,因此需要删选近期的帖子。我们可以对时间进行判断,只有一个月之内发布的帖子才进行爬取并存储。获取今天的日期使用datetime.now().date(),然后与爬取的帖子时间日期比较,timedelta可在日期上做天days时间计算,但需要将时间转换为时间形式。
实现部分关键代码如下所示:
完成了单个帖子的内容爬取之后,我们采用迭代方法把全部帖子爬取一遍。我们通过两层迭代方法,第一层为页数,第二层为一页的股吧帖子数,将每个帖子的URL存储在列表中,通过迭代的方式一个个爬取帖子的内容。<br />
实现部分关键代码如下:
当我们爬取时发现某个帖子不存在,出现爬取信息异常时,可使用try...except...进行异常处理。
最终爬取到的帖子内容如下图所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
5
帖子内容存储为txt
我们可以将爬取信息写到txt文件中,打开方式的代码实现如下所示,a+为在文本尾部追加写入,而不是覆盖写入,codecs.open这个方法可以指定编码打开文件,而使用Python内置的open打开文件只能写入str类型。
f=codecs.open(name,'a+','utf-8')
此处我们创建一个output_txt类,该类中我们会分别实现打开文件、写文件和关闭文件这几个方法。代码如下所示:
接下来就可以一边爬取帖子内容,一边把内容写入到txt文件中。实现关键代码如下所示:
写入txt文件的效果如下所示:
我们也可以把爬取信息写到GUI工具中,我们知道在wxPython中文本框为wx.TextCtrl类,该类可以显示和编辑文本,这样一来就可以把帖子信息写到GUI工具中。显示效果如下所示:
6
总结
本小节我们通过爬虫方式得到股吧帖子中的各种内容,那么这些内容对于我们来说有什么意义吗?我们发现总有些人一直在唱空,制造恐慌的情绪,不过我们可以通过分类分析下这些空头评论和股价的涨跌有没有什么关联,是不是有写ID是专门来唱空的呢?感兴趣的朋友们可以试试!比如用词云这种方式,如下所示:
查看全部
数据分析|爬虫抓取东方财富网股吧帖子
1前言
量化交易策略的研究主要涵盖了微观和宏观这两个方面,微观方面更多地是从市场价格和成交持仓这些基础信息为研究对象,通过算法计算出技术指标,再从技术指标的变化上构建交易模型。宏观方面则是基于更多的市场资讯开发交易模型,比如从CPI、PPI、货币发行量这些宏观经济指标为研究对象构建交易模型;或者是利用数据挖掘技术从新闻事件中挖掘出可能造成市场异常波动的事件,从而获得交易的时机。
我们知道知名股票论坛有点金投资家园、股天下、东方财富网股吧、和讯股吧、创幻论坛、MACD股市等等,笔者用的比较多的是东方财富网股吧。在课程《构建基于股票的量化交易系统》中我们以爬取东方财富网行业板块当日的行情数据为案例,介绍了网络爬虫的原理和方法,本节我们再介绍下如何爬取东方财富网股吧帖子的内容。
2
解析股吧帖子URL
首先通过浏览器访问伟星新材的股吧,查看该网页的URL为:
,002372.html,网页内容如下图所示:
当我们点击第2页、第3页后,查看下当前的URL分别为:
http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
因此得到了个股股吧URL的规律为:
, 002372_%d.html形式表示,
其中的规律比较直白,%d为论坛第几页,不过这个形式是按评论时间排列的网址,如果按发帖时间的排列网址是:
,002372,f_%d.html。
股吧的帖子由两部分组成,一部分为“财经评论”或“东方财富网”发布的公告或官方消息,另一部分为散户发布的讨论帖子,如下图所示:
前者的帖子URL为:
,cjpl,902659513.html,
后者的帖子URL为:
,002372,902629178.html
两者的URL都可在当前该股股吧HTML文件内容中搜寻到,如下所示:
因此“财经评论”、“东方财富网”或者散户发布的帖子,主要的特征为/news,在实现上我们可以先爬取到股吧HTML内容,然后通过正则表达式来筛选得到帖子的URL。
关于读取网页HTML内容的关键代码我们已经在课程《爬虫方式获取行业板块数据》一节中具体介绍过。需要注意的是Python2的urllib、urllib2和urlparse,已经在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的内容整合为urllib.request模块,urlparse整合为urllib.parse模块。
获取到HTML代码部分内容如下:
正则表达式筛选帖子URL,采用了pile和re.findall,实现代码如下:
其中正则表达式的\S+表示匹配多次非空白字符,然后使用findall函数找到匹配的所有字符串,并把它们作为一个列表返回。
然后是使用urljoin方法把整个url拼接好用于爬取单个帖子的标题内容,关键代码如下所示:
3创建爬虫URL队列
接下来我们把所有需要爬取的股吧页以及每页中的帖子的URL以队列的方式进行管理。Python中存储序列的类型有list、tuple、dict和set,它们之间的区别和特点简单的说:tuple不能修改其中的元素;set是无序集合,会自动去除重复元素;list是有序的集合;dict是一组key和value的组合。此次我们选择list作为队列的存储类型。
创建target_url_manager类,该类包含以下几个方法:
创建队列形式如下所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
4
解析股吧帖子内容
单个帖子爬取的内容包括三部分,帖子发表时间、作者及帖子标题,如下所示:
我们可以通过正则表达式进行提取,其中在组合正则表达式时,需要考虑到HTML代码中是否有重复的匹配关键字。作者和帖子标题正则代码如下,mainbody、zwcontentmain这些关键字在文本中仅出现一次,匹配程度较高。由于网站HTML代码的改动,表达式需要经常调整。
关键代码如下所示:
com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
发布时间正则代码如下,分两步逐渐明晰的去提取时间,由于search是扫描字符串找到这个RE 匹配的位置,因此增加group()返回匹配字符串。
pub_elems = re.search('.*?',html_cont2).group()#发表于 2020-02-11 09:54:48 东方财富Android版<br />pub_time = re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
<br />
另外,论坛帖子与当前的股价走势有时间联系,太早的帖子对现在无参考作用,因此需要删选近期的帖子。我们可以对时间进行判断,只有一个月之内发布的帖子才进行爬取并存储。获取今天的日期使用datetime.now().date(),然后与爬取的帖子时间日期比较,timedelta可在日期上做天days时间计算,但需要将时间转换为时间形式。
实现部分关键代码如下所示:
完成了单个帖子的内容爬取之后,我们采用迭代方法把全部帖子爬取一遍。我们通过两层迭代方法,第一层为页数,第二层为一页的股吧帖子数,将每个帖子的URL存储在列表中,通过迭代的方式一个个爬取帖子的内容。<br />
实现部分关键代码如下:
当我们爬取时发现某个帖子不存在,出现爬取信息异常时,可使用try...except...进行异常处理。
最终爬取到的帖子内容如下图所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
5
帖子内容存储为txt
我们可以将爬取信息写到txt文件中,打开方式的代码实现如下所示,a+为在文本尾部追加写入,而不是覆盖写入,codecs.open这个方法可以指定编码打开文件,而使用Python内置的open打开文件只能写入str类型。
f=codecs.open(name,'a+','utf-8')
此处我们创建一个output_txt类,该类中我们会分别实现打开文件、写文件和关闭文件这几个方法。代码如下所示:
接下来就可以一边爬取帖子内容,一边把内容写入到txt文件中。实现关键代码如下所示:
写入txt文件的效果如下所示:
我们也可以把爬取信息写到GUI工具中,我们知道在wxPython中文本框为wx.TextCtrl类,该类可以显示和编辑文本,这样一来就可以把帖子信息写到GUI工具中。显示效果如下所示:
6
总结
本小节我们通过爬虫方式得到股吧帖子中的各种内容,那么这些内容对于我们来说有什么意义吗?我们发现总有些人一直在唱空,制造恐慌的情绪,不过我们可以通过分类分析下这些空头评论和股价的涨跌有没有什么关联,是不是有写ID是专门来唱空的呢?感兴趣的朋友们可以试试!比如用词云这种方式,如下所示:
数据抓取学习3|web scraper爬虫使用方法—进阶篇
网站优化 • 优采云 发表了文章 • 0 个评论 • 779 次浏览 • 2022-06-20 04:44
上一篇文章讲了web scraper的基础操作,今天跟大家分享web scraper爬虫的一些进阶使用方法,学会了它,大概80%的网站元素都可以抓取了。
它的步骤都是:
创建一个站点Create sitemap—新增选择器Add new selector—点击Scrape抓取,不同的是选择器中Type的选择。
在进阶篇中,主要讲的就是这几个Type的使用。
目录
页内提取多个字段Type=Element
选择树Selector graph
选择快捷键Enable key
不规则分页Type=Element scroll down/Element click
二三级页面元素采集Type=Type=Link
抓取表单Type=Table
Delay的设置
1.页内提取多个字段(Type=Element)
如上图,如果想要同时抓取这个回答中的标题、点赞人数、回答的正文,就要用到Element这个选择器,它表示的是元素集,各个元素组成的一个元素集。比如上图中的回答中的标题、点赞人数、回答的正文、评论数就在一个元素集里。
具体的操作步骤如下:
新建一个站点地图Create sitemap—新建选择器Add new selector—新建子选择器—抓取
点击Select选取元素,这个是元素集,所以选择时要把整个元素集都框选中。具体步骤如下图,在基础篇中讲过,在选择时如果是type(1),说明这个页面的元素没有选完,这里再选择下一个元素集就可以了。
在新建选择器时选择Element这个选择器,勾选Multiple。
建好之后,点击这个选择器,进入到选择子器页面,然后再新建子选择器,选择需要抓取的页面元素。比如:标题、正文、点赞数、评论数。
子元素:标题、正文、点赞数、评论数这些都是文本,Type选择Text就可以了。
2.选择树Selector graph
在Sitemap的下拉菜单中有一个Selector graph的选择,通过它可以查看选择器之间的逻辑关系。
这个例子中元素集与元素之间的关系。
3.选择快捷键(Enable key)
用鼠标选择页面元素,有时候会出现选择错误或者是一点击就跳到的另外一个页面,这时候可以利用Enable key这个快捷操作去选取元素。
勾选Enable key ,把鼠标悬停在你要选择的元素上,待采集字段变绿后点击键盘S键选择。
4.不规则分页Type=Element scroll down/Element click
像下图中这种,需要鼠标向下滚动和点击“加载更多”,网页才会加载出新的内容。
这类网站的元素,可以分别利用选择器Type中的Element scroll down和Element click来进行抓取。
下面这个实例:收集IT桔子中金融类公司的公司名,公司简介。
这里需要鼠标点击“加载更多”才会出现新的内容。
新建一个站点地图后,新增选择器,在Type中选择Element click,点击Selector中的Select,选择元素集。
在Click selector点击Select,选择“加载更多”。
Click type 中选择Click more,因为这条类目内容很多,需要点击多次的“加载更多”,如果需要点击一次的话,选择Click once就可以。
Click element uniquenss选择unique CSS Selector。
勾选Multiple,注意在子选择器中就不用勾选。
这里加载可能会出现一点延时,所以可以加一个1000ms的延时。
然后再分别建立公司标题和公司简介的子选择器,进行抓取即可。
5.二三级页面元素采集Type=Link
还是知乎的例子,如果还想要收集这个问题的关注人数和浏览量,但这两个数据在另外一个页面,这里就需要用到选择器中Type=Link的选项,它表示的是指向这个文本背后的链接。
具体的操作步骤如下:
在元素集的子选择器中新建一个link的子选择器。
Type选择Link,选中标题,这里会看到出现标题的链接。
在link的下面再新建两个选择器,分别抓取关注和浏览量的数据。
看下这个抓取的逻辑树,理解就更清晰了:
6.抓取表单Type=Table
利用Type=Table
以抓取优采云票余票信息为例子。
网址链接:
在选择器中选择Type=Table,Selector选择整个表格。
Header row selector,选择表头,这例子中选择数据第一行为表头,再修改表头的名字,如果选择第一行为表头的话,只能抓取出发地、目的地、余票数量三个元素,详细的每日余票量抓取不了。
修改表头的标注
Data rows selector中选择所以抓取的数据项。
7.Delay的设置
在操作过程中,但选择器多了之后,大家会看到很多Delay的设置,下面说说需要设置Delay的情况。
点击Scrape后,这里的Delay,它针对的是全局,所有链接发生变化的情况。
点击分页、加载更多、滚动下拉这类页面需要时间加载是,就设置delay,推荐2000ms。
元素集中的子选择器可以不设置delay。
小结
讲解了web scraper的进阶操作后,是不是发现又有很多网站数据可以抓取了。
进阶篇中主要的知识点有:
1.根据抓取元素的不同情况,选择不同的Type
2.选择树Selector graph
选择器之间的逻辑关系。
3.选择快捷键Enable key
4.Delay的设置
页面需要时间加载的情况设置Delay,元素集中的子选择器可以不设 置。
5.子选择器中的Multiple不用勾选
6.常见的问题
操作过程中会需要两个常见问题:
思考题
在知乎例子的这个抓取结果中,回答正文中,没有把回答的全文抓取完。在网站上“阅读全文”这四个字需要用鼠标点开,爬虫才能把全部回答抓取完,怎么设置这个选择器呢?
大家可以先思考,尝试自己操作一下。
公众号回复“答案”,就可获取具体的操作步骤。
注:我学习课程为三节课的《人人都能学会的数据爬虫课》,此次仅为纯粹的学习分享。
搬运工的苦劳
苹果专用赞赏二维码 查看全部
数据抓取学习3|web scraper爬虫使用方法—进阶篇
上一篇文章讲了web scraper的基础操作,今天跟大家分享web scraper爬虫的一些进阶使用方法,学会了它,大概80%的网站元素都可以抓取了。
它的步骤都是:
创建一个站点Create sitemap—新增选择器Add new selector—点击Scrape抓取,不同的是选择器中Type的选择。
在进阶篇中,主要讲的就是这几个Type的使用。
目录
页内提取多个字段Type=Element
选择树Selector graph
选择快捷键Enable key
不规则分页Type=Element scroll down/Element click
二三级页面元素采集Type=Type=Link
抓取表单Type=Table
Delay的设置
1.页内提取多个字段(Type=Element)
如上图,如果想要同时抓取这个回答中的标题、点赞人数、回答的正文,就要用到Element这个选择器,它表示的是元素集,各个元素组成的一个元素集。比如上图中的回答中的标题、点赞人数、回答的正文、评论数就在一个元素集里。
具体的操作步骤如下:
新建一个站点地图Create sitemap—新建选择器Add new selector—新建子选择器—抓取
点击Select选取元素,这个是元素集,所以选择时要把整个元素集都框选中。具体步骤如下图,在基础篇中讲过,在选择时如果是type(1),说明这个页面的元素没有选完,这里再选择下一个元素集就可以了。
在新建选择器时选择Element这个选择器,勾选Multiple。
建好之后,点击这个选择器,进入到选择子器页面,然后再新建子选择器,选择需要抓取的页面元素。比如:标题、正文、点赞数、评论数。
子元素:标题、正文、点赞数、评论数这些都是文本,Type选择Text就可以了。
2.选择树Selector graph
在Sitemap的下拉菜单中有一个Selector graph的选择,通过它可以查看选择器之间的逻辑关系。
这个例子中元素集与元素之间的关系。
3.选择快捷键(Enable key)
用鼠标选择页面元素,有时候会出现选择错误或者是一点击就跳到的另外一个页面,这时候可以利用Enable key这个快捷操作去选取元素。
勾选Enable key ,把鼠标悬停在你要选择的元素上,待采集字段变绿后点击键盘S键选择。
4.不规则分页Type=Element scroll down/Element click
像下图中这种,需要鼠标向下滚动和点击“加载更多”,网页才会加载出新的内容。
这类网站的元素,可以分别利用选择器Type中的Element scroll down和Element click来进行抓取。
下面这个实例:收集IT桔子中金融类公司的公司名,公司简介。
这里需要鼠标点击“加载更多”才会出现新的内容。
新建一个站点地图后,新增选择器,在Type中选择Element click,点击Selector中的Select,选择元素集。
在Click selector点击Select,选择“加载更多”。
Click type 中选择Click more,因为这条类目内容很多,需要点击多次的“加载更多”,如果需要点击一次的话,选择Click once就可以。
Click element uniquenss选择unique CSS Selector。
勾选Multiple,注意在子选择器中就不用勾选。
这里加载可能会出现一点延时,所以可以加一个1000ms的延时。
然后再分别建立公司标题和公司简介的子选择器,进行抓取即可。
5.二三级页面元素采集Type=Link
还是知乎的例子,如果还想要收集这个问题的关注人数和浏览量,但这两个数据在另外一个页面,这里就需要用到选择器中Type=Link的选项,它表示的是指向这个文本背后的链接。
具体的操作步骤如下:
在元素集的子选择器中新建一个link的子选择器。
Type选择Link,选中标题,这里会看到出现标题的链接。
在link的下面再新建两个选择器,分别抓取关注和浏览量的数据。
看下这个抓取的逻辑树,理解就更清晰了:
6.抓取表单Type=Table
利用Type=Table
以抓取优采云票余票信息为例子。
网址链接:
在选择器中选择Type=Table,Selector选择整个表格。
Header row selector,选择表头,这例子中选择数据第一行为表头,再修改表头的名字,如果选择第一行为表头的话,只能抓取出发地、目的地、余票数量三个元素,详细的每日余票量抓取不了。
修改表头的标注
Data rows selector中选择所以抓取的数据项。
7.Delay的设置
在操作过程中,但选择器多了之后,大家会看到很多Delay的设置,下面说说需要设置Delay的情况。
点击Scrape后,这里的Delay,它针对的是全局,所有链接发生变化的情况。
点击分页、加载更多、滚动下拉这类页面需要时间加载是,就设置delay,推荐2000ms。
元素集中的子选择器可以不设置delay。
小结
讲解了web scraper的进阶操作后,是不是发现又有很多网站数据可以抓取了。
进阶篇中主要的知识点有:
1.根据抓取元素的不同情况,选择不同的Type
2.选择树Selector graph
选择器之间的逻辑关系。
3.选择快捷键Enable key
4.Delay的设置
页面需要时间加载的情况设置Delay,元素集中的子选择器可以不设 置。
5.子选择器中的Multiple不用勾选
6.常见的问题
操作过程中会需要两个常见问题:
思考题
在知乎例子的这个抓取结果中,回答正文中,没有把回答的全文抓取完。在网站上“阅读全文”这四个字需要用鼠标点开,爬虫才能把全部回答抓取完,怎么设置这个选择器呢?
大家可以先思考,尝试自己操作一下。
公众号回复“答案”,就可获取具体的操作步骤。
注:我学习课程为三节课的《人人都能学会的数据爬虫课》,此次仅为纯粹的学习分享。
搬运工的苦劳
苹果专用赞赏二维码
Python爬虫之三:抓取猫眼电影TOP100
网站优化 • 优采云 发表了文章 • 0 个评论 • 107 次浏览 • 2022-06-18 02:42
今天我要利用requests库和正则表达式抓取猫眼电影Top100榜单。
运行平台:Windows
Python版本:Python3.6
IDE:Sublime Text
其他工具:Chrome浏览器
1. 抓取单页内容
浏览器打开猫眼电影首页,点击“榜单”,然后再点击"TOP100榜",就能看到想要的了。
接下来通过代码来获取网页的HTML代码。
运行结果如下:
2. 正则表达式提取有用信息
在上图中,已经标注出我们将要提取的内容,下面用代码实现:
运行结果如下:
3. 保存信息
获取电影信息之后,要保存起来留用。要保存的有文本信息和电影封面。
下面为保存结果:
4.下载TOP100所有电影信息
通过点击标签页发现只是URL变化了:
修改main函数以动态改变URL:
到此我们已经将TOP100的电影信息和封面全部得到了。
5.多线程抓取
此次抓取的数据不算多,但是为了学习,使用多进程进行抓取,以应对以后大量的数据抓取。
下面为普通抓取和多进程抓取的时间对比:
以下为完整代码: 查看全部
Python爬虫之三:抓取猫眼电影TOP100
今天我要利用requests库和正则表达式抓取猫眼电影Top100榜单。
运行平台:Windows
Python版本:Python3.6
IDE:Sublime Text
其他工具:Chrome浏览器
1. 抓取单页内容
浏览器打开猫眼电影首页,点击“榜单”,然后再点击"TOP100榜",就能看到想要的了。
接下来通过代码来获取网页的HTML代码。
运行结果如下:
2. 正则表达式提取有用信息
在上图中,已经标注出我们将要提取的内容,下面用代码实现:
运行结果如下:
3. 保存信息
获取电影信息之后,要保存起来留用。要保存的有文本信息和电影封面。
下面为保存结果:
4.下载TOP100所有电影信息
通过点击标签页发现只是URL变化了:
修改main函数以动态改变URL:
到此我们已经将TOP100的电影信息和封面全部得到了。
5.多线程抓取
此次抓取的数据不算多,但是为了学习,使用多进程进行抓取,以应对以后大量的数据抓取。
下面为普通抓取和多进程抓取的时间对比:
以下为完整代码:
高性能异步并发爬虫!- colly 自动抓取资讯
网站优化 • 优采云 发表了文章 • 0 个评论 • 219 次浏览 • 2022-06-12 08:31
colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬虫界的大佬。本文用其抓取博文资讯,从收集器实例配置,goQuery 进行 dom 节点数据抓取,自动分页访问,到 csv 数据持久化,json 控制台输出,全程简单直观。
Code
抓取数据入口为社区某用户博客列表页,比如
package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog数据<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 数据持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.准备收集器实例<br /> c := colly.NewCollector(<br /> // 开启本机debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止页面重复下载<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析页面数据<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子项<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正则匹配替换,字符串转整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一页<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 启动<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 输出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 显示收集器的打印信息<br /> log.Println(c)<br />}<br />
Output
控制台输出
....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 与 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 进阶笔记",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在线聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
csv 文本输出
ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取动态网页,https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名类 与 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大话并发,https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元运算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,笔试之 模板变量替换,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,笔试之 连续数增维,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,笔试之 一行代码求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
Colly 查看全部
高性能异步并发爬虫!- colly 自动抓取资讯
colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬虫界的大佬。本文用其抓取博文资讯,从收集器实例配置,goQuery 进行 dom 节点数据抓取,自动分页访问,到 csv 数据持久化,json 控制台输出,全程简单直观。
Code
抓取数据入口为社区某用户博客列表页,比如
package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog数据<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 数据持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.准备收集器实例<br /> c := colly.NewCollector(<br /> // 开启本机debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止页面重复下载<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析页面数据<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子项<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正则匹配替换,字符串转整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一页<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 启动<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 输出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 显示收集器的打印信息<br /> log.Println(c)<br />}<br />
Output
控制台输出
....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 与 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 进阶笔记",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在线聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
csv 文本输出
ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取动态网页,https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名类 与 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大话并发,https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元运算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,笔试之 模板变量替换,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,笔试之 连续数增维,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,笔试之 一行代码求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
Colly
Python网页爬虫&文本处理&科学计算&机器学习&数据挖掘兵器谱(转)
网站优化 • 优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2022-06-07 06:58
已获得授权
周末时看到这篇不错的文章,其中介绍了诸多python第三方库和工具,与大家分享下,也算是门可罗雀的本号第一次转载文章。后续看到精彩的文章也会继续分享。
Image Photograph by Pavliha Getty
曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python。
离开腾讯创业后,第一个作品课程图谱也是选择了Python系的Flask框架,渐渐的将自己的绝大部分工作交给了Python。这些年来,接触和使用了很多Python工具包,特别是在文本处理,科学计算,机器学习和数据挖掘领域,有很多很多优秀的Python工具包可供使用,所以作为Pythoner,也是相当幸福的。
其实如果仔细留意微博,你会发现很多这方面的分享,自己也Google了一下,发现也有同学总结了“Python机器学习库”,不过总感觉缺少点什么。最近流行一个词,全栈工程师(full stack engineer),作为一个苦逼的创业者,天然的要把自己打造成一个full stack engineer,而这个过程中,这些Python工具包给自己提供了足够的火力,所以想起了这个系列。
当然,这也仅仅是抛砖引玉,希望大家能提供更多的线索,来汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱。
一、Python网页爬虫工具集
一个真实的项目,一定是从获取数据开始的。无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,我们也就从这里开始了:
1.Scrapy
Scrapy, a fast high-level screen scraping and web crawling framework for Python.
鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课程都是依靠Scrapy抓去的,这方面的介绍文章有很多,推荐大牛pluskid早年的一篇文章:《Scrapy 轻松定制网络爬虫》,历久弥新。
官方主页:
Github代码页:
2.Beautiful Soup
You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
读书的时候通过《集体智慧编程》这本书知道Beautiful Soup的,后来也偶尔会用用,非常棒的一套工具。客观的说,Beautifu Soup不完全是一套爬虫工具,需要配合urllib使用,而是一套HTML/XML数据分析,清洗和获取工具。
官方主页:
3.Python-Goose
Html Content / Article Extractor, web scrapping lib in Python
Goose最早是用Java写得,后来用Scala重写,是一个Scala项目。Python-Goose用Python重写,依赖了Beautiful Soup。前段时间用过,感觉很不错,给定一个文章的URL, 获取文章的标题和内容很方便。
Github主页:
二、Python文本处理工具集
从网页上获取文本数据之后,依据任务的不同,就需要进行基本的文本处理了,譬如对于英文来说,需要基本的tokenize,对于中文,则需要常见的中文分词,进一步的话,无论英文中文,还可以词性标注,句法分析,关键词提取,文本分类,情感分析等等。这个方面,特别是面向英文领域,有很多优秀的工具包,我们一一道来。
1.NLTK— Natural Language Toolkit
NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
搞自然语言处理的同学应该没有人不知道NLTK吧,这里也就不多说了。不过推荐两本书籍给刚刚接触NLTK或者需要详细了解NLTK的同学: 一个是官方的《Natural Language Processing with Python》,以介绍NLTK里的功能用法为主,同时附带一些Python知识,同时国内陈涛同学友情翻译了一个中文版,这里可以看到:推荐《用Python进行自然语言处理》中文翻译-NLTK配套书;另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,这本书要深入一些,会涉及到NLTK的代码结构,同时会介绍如何定制自己的语料和模型等,相当不错。
官方主页:
Github代码页:
2.Pattern
Pattern is a web mining module for the Python programming language.
It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
Pattern由比利时安特卫普大学CLiPS实验室出品,客观的说,Pattern不仅仅是一套文本处理工具,它更是一套web数据挖掘工具,囊括了数据抓取模块(包括Google, Twitter, 维基百科的API,以及爬虫和HTML分析器),文本处理模块(词性标注,情感分析等),机器学习模块(VSM, 聚类,SVM)以及可视化模块等,可以说,Pattern的这一整套逻辑也是这篇文章的组织逻辑,不过这里我们暂且把Pattern放到文本处理部分。我个人主要使用的是它的英文处理模块Pattern.en, 有很多很不错的文本处理功能,包括基础的tokenize, 词性标注,句子切分,语法检查,拼写纠错,情感分析,句法分析等,相当不错。
官方主页:
3.TextBlob: Simplified Text Processing
TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
TextBlob是一个很有意思的Python文本处理工具包,它其实是基于上面两个Python工具包NLKT和Pattern做了封装(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同时提供了很多文本处理功能的接口,包括词性标注,名词短语提取,情感分析,文本分类,拼写检查等,甚至包括翻译和语言检测,不过这个是基于Google的API的,有调用次数限制。TextBlob相对比较年轻,有兴趣的同学可以关注。
官方主页:
Github代码页:
4.MBSPfor Python
MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
MBSP与Pattern同源,同出自比利时安特卫普大学CLiPS实验室,提供了Word Tokenization, 句子切分,词性标注,Chunking, Lemmatization,句法分析等基本的文本处理功能,感兴趣的同学可以关注。
官方主页:
5.Gensim: Topic modeling for humans
Gensim是一个相当专业的主题模型Python工具包,无论是代码还是文档,我们曾经用《如何计算两个文档的相似度》介绍过Gensim的安装和使用过程,这里就不多说了。
官方主页:
github代码页:
6.langid.py: Stand-alone language identification system
语言检测是一个很有意思的话题,不过相对比较成熟,这方面的解决方案很多,也有很多不错的开源工具包,不过对于Python来说,我使用过langid这个工具包,也非常愿意推荐它。langid目前支持97种语言的检测,提供了很多易用的功能,包括可以启动一个建议的server,通过json调用其API,可定制训练自己的语言检测模型等,可以说是“麻雀虽小,五脏俱全”。
Github主页:
7.Jieba: 结巴中文分词
“结巴”中文分词:做最好的Python中文分词组件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
好了,终于可以说一个国内的Python文本处理工具包了:结巴分词,其功能包括支持三种分词模式(精确模式、全模式、搜索引擎模式),支持繁体分词,支持自定义词典等,是目前一个非常不错的Python中文分词解决方案。
Github主页:
8.xTAS
xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
感谢微博朋友@大山坡的春提供的线索:我们组同事之前发布了xTAS,也是基于python的text mining工具包,欢迎使用,链接:。看起来很不错的样子,回头试用一下。
Github代码页:
三、Python科学计算工具包
说起科学计算,大家首先想起的是Matlab,集数值计算,可视化工具及交互于一身,不过可惜是一个商业产品。开源方面除了GNU Octave在尝试做一个类似Matlab的工具包外,Python的这几个工具包集合到一起也可以替代Matlab的相应功能:NumPy+SciPy+Matplotlib+iPython。同时,这几个工具包,特别是NumPy和SciPy,也是很多Python文本处理 & 机器学习 & 数据挖掘工具包的基础,非常重要。最后再推荐一个系列《用Python做科学计算》,将会涉及到NumPy, SciPy, Matplotlib,可以做参考。
1.NumPy
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
1)a powerful N-dimensional array object
2)sophisticated (broadcasting) functions
3)tools for integrating C/C++ and Fortran code
4) useful linear algebra, Fourier transform, and random number capabilities
Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
NumPy几乎是一个无法回避的科学计算工具包,最常用的也许是它的N维数组对象,其他还包括一些成熟的函数库,用于整合C/C++和Fortran代码的工具包,线性代数、傅里叶变换和随机数生成函数等。NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。
官方主页:
2.SciPy:Scientific Computing Tools for Python
SciPy refers to several related but distinct entities:
1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
2)The community of people who use and develop this stack.
3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
“SciPy是一个开源的Python算法库和数学工具包,SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。其功能与软件MATLAB、Scilab和GNU Octave类似。 Numpy和Scipy常常结合着使用,Python大多数机器学习库都依赖于这两个模块。”—-引用自“Python机器学习库”
官方主页:
3.Matplotlib
matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB®* or Mathematica®†), web application servers, and six graphical user interface toolkits.
matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。Matplotlib可以配合ipython shell使用,提供不亚于Matlab的绘图体验,总之用过了都说好。
官方主页:
4.iPython
IPython provides a rich architecture for interactive computing with:
1)Powerful interactive shells (terminal and Qt-based).
2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
3)Support for interactive data visualization and use of GUI toolkits.
4)Flexible, embeddable interpreters to load into your own projects.
5)Easy to use, high performance tools for parallel computing.
“iPython 是一个Python 的交互式Shell,比默认的Python Shell 好用得多,功能也更强大。 她支持语法高亮、自动完成、代码调试、对象自省,支持 Bash Shell 命令,内置了许多很有用的功能和函式等,非常容易使用。 ” 启动iPython的时候用这个命令“ipython –pylab”,默认开启了matploblib的绘图交互,用起来很方便。
官方主页:
四、Python 机器学习 & 数据挖掘 工具包
机器学习和数据挖掘这两个概念不太好区分,这里就放到一起了。这方面的开源Python工具包有很多,这里先从熟悉的讲起,再补充其他来源的资料,也欢迎大家补充。
1.scikit-learn: Machine Learning in Python
scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
首先推荐大名鼎鼎的scikit-learn,scikit-learn是一个基于NumPy, SciPy, Matplotlib的开源机器学习工具包,主要涵盖分类,回归和聚类算法,例如SVM, 逻辑回归,朴素贝叶斯,随机森林,k-means等算法,代码和文档都非常不错,在许多Python项目中都有应用。例如在我们熟悉的NLTK中,分类器方面就有专门针对scikit-learn的接口,可以调用scikit-learn的分类算法以及训练数据来训练分类器模型。这里推荐一个视频,也是我早期遇到scikit-learn的时候推荐过的:推荐一个Python机器学习工具包Scikit-learn以及相关视频–Tutorial: scikit-learn – Machine Learning in Python
官方主页:
2.Pandas: Python Data Analysis Library
Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
第一次接触Pandas是由于Udacity上的一门数据分析课程“Introduction to Data Science” 的Project需要用Pandas库,所以学习了一下Pandas。Pandas也是基于NumPy和Matplotlib开发的,主要用于数据分析和数据可视化,它的数据结构DataFrame和R语言里的data.frame很像,特别是对于时间序列数据有自己的一套分析机制,非常不错。这里推荐一本书《Python for Data Analysis》,作者是Pandas的主力开发,依次介绍了iPython, NumPy, Pandas里的相关功能,数据可视化,数据清洗和加工,时间数据处理等,案例包括金融股票数据挖掘等,相当不错。
官方主页:
=====================================================
分割线,以上工具包基本上都是自己用过的,以下来源于其他同学的线索,特别是《Python机器学习库》,《23个python的机器学习包》,做了一点增删修改,欢迎大家补充
=====================================================
3.mlpy – Machine Learning Python
mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
官方主页:
4.MDP:The Modular toolkit for Data Processing
Modular toolkit for Data Processing (MDP) is a Python data processing framework.
From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
“MDP用于数据处理的模块化工具包,一个Python数据处理框架。 从用户的观点,MDP是能够被整合到数据处理序列和更复杂的前馈网络结构的一批监督学习和非监督学习算法和其他数据处理单元。计算依照速度和内存需求而高效的执行。从科学开发者的观点,MDP是一个模块框架,它能够被容易地扩展。新算法的实现是容易且直观的。新实现的单元然后被自动地与程序库的其余部件进行整合。MDP在神经科学的理论研究背景下被编写,但是它已经被设计为在使用可训练数据处理算法的任何情况中都是有用的。其站在用户一边的简单性,各种不同的随时可用的算法,及应用单元的可重用性,使得它也是一个有用的教学工具。”
官方主页:
5.PyBrain
PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
“PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一个机器学习模块,它的目标是为机器学习任务提供灵活、易应、强大的机器学习算法。(这名字很霸气)
PyBrain正如其名,包括神经网络、强化学习(及二者结合)、无监督学习、进化算法。因为目前的许多问题需要处理连续态和行为空间,必须使用函数逼近(如神经网络)以应对高维数据。PyBrain以神经网络为核心,所有的训练方法都以神经网络为一个实例。”
官方主页:
6.PyML– machine learning in Python
PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
“PyML是一个Python机器学习工具包,为各分类和回归方法提供灵活的架构。它主要提供特征选择、模型选择、组合分类器、分类评估等功能。”
项目主页:
7.Milk:Machine learning toolkit in Python.
Its focus is on supervised classification with several classifiers available:
SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
feature selection. These classifiers can be combined in many ways to form
different classification systems.
“Milk是Python的一个机器学习工具箱,其重点是提供监督分类法与几种有效的分类分析:SVMs(基于libsvm),K-NN,随机森林经济和决策树。它还可以进行特征选择。这些分类可以在许多方面相结合,形成不同的分类系统。对于无监督学习,它提供K-means和affinity propagation聚类算法。”
官方主页:
8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
“PyMVPA(Multivariate Pattern Analysis in Python)是为大数据集提供统计学习分析的Python工具包,它提供了一个灵活可扩展的框架。它提供的功能有分类、回归、特征选择、数据导入导出、可视化等”
官方主页:
9.Pyrallel– Parallel Data Analytics in Python
Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
“Pyrallel(Parallel Data Analytics in Python)基于分布式计算模式的机器学习和半交互式的试验项目,可在小型集群上运行”
Github代码页:
10.Monte– gradient based learning in Python
Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
“Monte (machine learning in pure Python)是一个纯Python机器学习库。它可以迅速构建神经网络、条件随机场、逻辑回归等模型,使用inline-C优化,极易使用和扩展。”
官方主页:
11.Theano
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
5)dynamic C code generation – Evaluate expressions faster.
6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
“Theano 是一个 Python 库,用来定义、优化和模拟数学表达式计算,用于高效的解决多维数组的计算问题。Theano的特点:紧密集成Numpy;高效的数据密集型GPU计算;高效的符号微分运算;高速和稳定的优化;动态生成c代码;广泛的单元测试和自我验证。自2007年以来,Theano已被广泛应用于科学运算。theano使得构建深度学习模型更加容易,可以快速实现多种模型。PS:Theano,一位希腊美女,Croton最有权势的Milo的女儿,后来成为了毕达哥拉斯的老婆。”
12.Pylearn2
Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
“Pylearn2建立在theano上,部分依赖scikit-learn上,目前Pylearn2正处于开发中,将可以处理向量、图像、视频等数据,提供MLP、RBM、SDA等深度学习模型。”
官方主页:
其他的,欢迎大家补充。
欢迎关注“牛衣古柳”
门可罗雀,快来捕鸟!
查看全部
Python网页爬虫&文本处理&科学计算&机器学习&数据挖掘兵器谱(转)
已获得授权
周末时看到这篇不错的文章,其中介绍了诸多python第三方库和工具,与大家分享下,也算是门可罗雀的本号第一次转载文章。后续看到精彩的文章也会继续分享。
Image Photograph by Pavliha Getty
曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python。
离开腾讯创业后,第一个作品课程图谱也是选择了Python系的Flask框架,渐渐的将自己的绝大部分工作交给了Python。这些年来,接触和使用了很多Python工具包,特别是在文本处理,科学计算,机器学习和数据挖掘领域,有很多很多优秀的Python工具包可供使用,所以作为Pythoner,也是相当幸福的。
其实如果仔细留意微博,你会发现很多这方面的分享,自己也Google了一下,发现也有同学总结了“Python机器学习库”,不过总感觉缺少点什么。最近流行一个词,全栈工程师(full stack engineer),作为一个苦逼的创业者,天然的要把自己打造成一个full stack engineer,而这个过程中,这些Python工具包给自己提供了足够的火力,所以想起了这个系列。
当然,这也仅仅是抛砖引玉,希望大家能提供更多的线索,来汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱。
一、Python网页爬虫工具集
一个真实的项目,一定是从获取数据开始的。无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,我们也就从这里开始了:
1.Scrapy
Scrapy, a fast high-level screen scraping and web crawling framework for Python.
鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课程都是依靠Scrapy抓去的,这方面的介绍文章有很多,推荐大牛pluskid早年的一篇文章:《Scrapy 轻松定制网络爬虫》,历久弥新。
官方主页:
Github代码页:
2.Beautiful Soup
You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
读书的时候通过《集体智慧编程》这本书知道Beautiful Soup的,后来也偶尔会用用,非常棒的一套工具。客观的说,Beautifu Soup不完全是一套爬虫工具,需要配合urllib使用,而是一套HTML/XML数据分析,清洗和获取工具。
官方主页:
3.Python-Goose
Html Content / Article Extractor, web scrapping lib in Python
Goose最早是用Java写得,后来用Scala重写,是一个Scala项目。Python-Goose用Python重写,依赖了Beautiful Soup。前段时间用过,感觉很不错,给定一个文章的URL, 获取文章的标题和内容很方便。
Github主页:
二、Python文本处理工具集
从网页上获取文本数据之后,依据任务的不同,就需要进行基本的文本处理了,譬如对于英文来说,需要基本的tokenize,对于中文,则需要常见的中文分词,进一步的话,无论英文中文,还可以词性标注,句法分析,关键词提取,文本分类,情感分析等等。这个方面,特别是面向英文领域,有很多优秀的工具包,我们一一道来。
1.NLTK— Natural Language Toolkit
NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
搞自然语言处理的同学应该没有人不知道NLTK吧,这里也就不多说了。不过推荐两本书籍给刚刚接触NLTK或者需要详细了解NLTK的同学: 一个是官方的《Natural Language Processing with Python》,以介绍NLTK里的功能用法为主,同时附带一些Python知识,同时国内陈涛同学友情翻译了一个中文版,这里可以看到:推荐《用Python进行自然语言处理》中文翻译-NLTK配套书;另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,这本书要深入一些,会涉及到NLTK的代码结构,同时会介绍如何定制自己的语料和模型等,相当不错。
官方主页:
Github代码页:
2.Pattern
Pattern is a web mining module for the Python programming language.
It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
Pattern由比利时安特卫普大学CLiPS实验室出品,客观的说,Pattern不仅仅是一套文本处理工具,它更是一套web数据挖掘工具,囊括了数据抓取模块(包括Google, Twitter, 维基百科的API,以及爬虫和HTML分析器),文本处理模块(词性标注,情感分析等),机器学习模块(VSM, 聚类,SVM)以及可视化模块等,可以说,Pattern的这一整套逻辑也是这篇文章的组织逻辑,不过这里我们暂且把Pattern放到文本处理部分。我个人主要使用的是它的英文处理模块Pattern.en, 有很多很不错的文本处理功能,包括基础的tokenize, 词性标注,句子切分,语法检查,拼写纠错,情感分析,句法分析等,相当不错。
官方主页:
3.TextBlob: Simplified Text Processing
TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
TextBlob是一个很有意思的Python文本处理工具包,它其实是基于上面两个Python工具包NLKT和Pattern做了封装(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同时提供了很多文本处理功能的接口,包括词性标注,名词短语提取,情感分析,文本分类,拼写检查等,甚至包括翻译和语言检测,不过这个是基于Google的API的,有调用次数限制。TextBlob相对比较年轻,有兴趣的同学可以关注。
官方主页:
Github代码页:
4.MBSPfor Python
MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
MBSP与Pattern同源,同出自比利时安特卫普大学CLiPS实验室,提供了Word Tokenization, 句子切分,词性标注,Chunking, Lemmatization,句法分析等基本的文本处理功能,感兴趣的同学可以关注。
官方主页:
5.Gensim: Topic modeling for humans
Gensim是一个相当专业的主题模型Python工具包,无论是代码还是文档,我们曾经用《如何计算两个文档的相似度》介绍过Gensim的安装和使用过程,这里就不多说了。
官方主页:
github代码页:
6.langid.py: Stand-alone language identification system
语言检测是一个很有意思的话题,不过相对比较成熟,这方面的解决方案很多,也有很多不错的开源工具包,不过对于Python来说,我使用过langid这个工具包,也非常愿意推荐它。langid目前支持97种语言的检测,提供了很多易用的功能,包括可以启动一个建议的server,通过json调用其API,可定制训练自己的语言检测模型等,可以说是“麻雀虽小,五脏俱全”。
Github主页:
7.Jieba: 结巴中文分词
“结巴”中文分词:做最好的Python中文分词组件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
好了,终于可以说一个国内的Python文本处理工具包了:结巴分词,其功能包括支持三种分词模式(精确模式、全模式、搜索引擎模式),支持繁体分词,支持自定义词典等,是目前一个非常不错的Python中文分词解决方案。
Github主页:
8.xTAS
xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
感谢微博朋友@大山坡的春提供的线索:我们组同事之前发布了xTAS,也是基于python的text mining工具包,欢迎使用,链接:。看起来很不错的样子,回头试用一下。
Github代码页:
三、Python科学计算工具包
说起科学计算,大家首先想起的是Matlab,集数值计算,可视化工具及交互于一身,不过可惜是一个商业产品。开源方面除了GNU Octave在尝试做一个类似Matlab的工具包外,Python的这几个工具包集合到一起也可以替代Matlab的相应功能:NumPy+SciPy+Matplotlib+iPython。同时,这几个工具包,特别是NumPy和SciPy,也是很多Python文本处理 & 机器学习 & 数据挖掘工具包的基础,非常重要。最后再推荐一个系列《用Python做科学计算》,将会涉及到NumPy, SciPy, Matplotlib,可以做参考。
1.NumPy
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
1)a powerful N-dimensional array object
2)sophisticated (broadcasting) functions
3)tools for integrating C/C++ and Fortran code
4) useful linear algebra, Fourier transform, and random number capabilities
Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
NumPy几乎是一个无法回避的科学计算工具包,最常用的也许是它的N维数组对象,其他还包括一些成熟的函数库,用于整合C/C++和Fortran代码的工具包,线性代数、傅里叶变换和随机数生成函数等。NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。
官方主页:
2.SciPy:Scientific Computing Tools for Python
SciPy refers to several related but distinct entities:
1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
2)The community of people who use and develop this stack.
3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
“SciPy是一个开源的Python算法库和数学工具包,SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。其功能与软件MATLAB、Scilab和GNU Octave类似。 Numpy和Scipy常常结合着使用,Python大多数机器学习库都依赖于这两个模块。”—-引用自“Python机器学习库”
官方主页:
3.Matplotlib
matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB®* or Mathematica®†), web application servers, and six graphical user interface toolkits.
matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。Matplotlib可以配合ipython shell使用,提供不亚于Matlab的绘图体验,总之用过了都说好。
官方主页:
4.iPython
IPython provides a rich architecture for interactive computing with:
1)Powerful interactive shells (terminal and Qt-based).
2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
3)Support for interactive data visualization and use of GUI toolkits.
4)Flexible, embeddable interpreters to load into your own projects.
5)Easy to use, high performance tools for parallel computing.
“iPython 是一个Python 的交互式Shell,比默认的Python Shell 好用得多,功能也更强大。 她支持语法高亮、自动完成、代码调试、对象自省,支持 Bash Shell 命令,内置了许多很有用的功能和函式等,非常容易使用。 ” 启动iPython的时候用这个命令“ipython –pylab”,默认开启了matploblib的绘图交互,用起来很方便。
官方主页:
四、Python 机器学习 & 数据挖掘 工具包
机器学习和数据挖掘这两个概念不太好区分,这里就放到一起了。这方面的开源Python工具包有很多,这里先从熟悉的讲起,再补充其他来源的资料,也欢迎大家补充。
1.scikit-learn: Machine Learning in Python
scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
首先推荐大名鼎鼎的scikit-learn,scikit-learn是一个基于NumPy, SciPy, Matplotlib的开源机器学习工具包,主要涵盖分类,回归和聚类算法,例如SVM, 逻辑回归,朴素贝叶斯,随机森林,k-means等算法,代码和文档都非常不错,在许多Python项目中都有应用。例如在我们熟悉的NLTK中,分类器方面就有专门针对scikit-learn的接口,可以调用scikit-learn的分类算法以及训练数据来训练分类器模型。这里推荐一个视频,也是我早期遇到scikit-learn的时候推荐过的:推荐一个Python机器学习工具包Scikit-learn以及相关视频–Tutorial: scikit-learn – Machine Learning in Python
官方主页:
2.Pandas: Python Data Analysis Library
Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
第一次接触Pandas是由于Udacity上的一门数据分析课程“Introduction to Data Science” 的Project需要用Pandas库,所以学习了一下Pandas。Pandas也是基于NumPy和Matplotlib开发的,主要用于数据分析和数据可视化,它的数据结构DataFrame和R语言里的data.frame很像,特别是对于时间序列数据有自己的一套分析机制,非常不错。这里推荐一本书《Python for Data Analysis》,作者是Pandas的主力开发,依次介绍了iPython, NumPy, Pandas里的相关功能,数据可视化,数据清洗和加工,时间数据处理等,案例包括金融股票数据挖掘等,相当不错。
官方主页:
=====================================================
分割线,以上工具包基本上都是自己用过的,以下来源于其他同学的线索,特别是《Python机器学习库》,《23个python的机器学习包》,做了一点增删修改,欢迎大家补充
=====================================================
3.mlpy – Machine Learning Python
mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
官方主页:
4.MDP:The Modular toolkit for Data Processing
Modular toolkit for Data Processing (MDP) is a Python data processing framework.
From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
“MDP用于数据处理的模块化工具包,一个Python数据处理框架。 从用户的观点,MDP是能够被整合到数据处理序列和更复杂的前馈网络结构的一批监督学习和非监督学习算法和其他数据处理单元。计算依照速度和内存需求而高效的执行。从科学开发者的观点,MDP是一个模块框架,它能够被容易地扩展。新算法的实现是容易且直观的。新实现的单元然后被自动地与程序库的其余部件进行整合。MDP在神经科学的理论研究背景下被编写,但是它已经被设计为在使用可训练数据处理算法的任何情况中都是有用的。其站在用户一边的简单性,各种不同的随时可用的算法,及应用单元的可重用性,使得它也是一个有用的教学工具。”
官方主页:
5.PyBrain
PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
“PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一个机器学习模块,它的目标是为机器学习任务提供灵活、易应、强大的机器学习算法。(这名字很霸气)
PyBrain正如其名,包括神经网络、强化学习(及二者结合)、无监督学习、进化算法。因为目前的许多问题需要处理连续态和行为空间,必须使用函数逼近(如神经网络)以应对高维数据。PyBrain以神经网络为核心,所有的训练方法都以神经网络为一个实例。”
官方主页:
6.PyML– machine learning in Python
PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
“PyML是一个Python机器学习工具包,为各分类和回归方法提供灵活的架构。它主要提供特征选择、模型选择、组合分类器、分类评估等功能。”
项目主页:
7.Milk:Machine learning toolkit in Python.
Its focus is on supervised classification with several classifiers available:
SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
feature selection. These classifiers can be combined in many ways to form
different classification systems.
“Milk是Python的一个机器学习工具箱,其重点是提供监督分类法与几种有效的分类分析:SVMs(基于libsvm),K-NN,随机森林经济和决策树。它还可以进行特征选择。这些分类可以在许多方面相结合,形成不同的分类系统。对于无监督学习,它提供K-means和affinity propagation聚类算法。”
官方主页:
8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
“PyMVPA(Multivariate Pattern Analysis in Python)是为大数据集提供统计学习分析的Python工具包,它提供了一个灵活可扩展的框架。它提供的功能有分类、回归、特征选择、数据导入导出、可视化等”
官方主页:
9.Pyrallel– Parallel Data Analytics in Python
Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
“Pyrallel(Parallel Data Analytics in Python)基于分布式计算模式的机器学习和半交互式的试验项目,可在小型集群上运行”
Github代码页:
10.Monte– gradient based learning in Python
Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
“Monte (machine learning in pure Python)是一个纯Python机器学习库。它可以迅速构建神经网络、条件随机场、逻辑回归等模型,使用inline-C优化,极易使用和扩展。”
官方主页:
11.Theano
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
5)dynamic C code generation – Evaluate expressions faster.
6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
“Theano 是一个 Python 库,用来定义、优化和模拟数学表达式计算,用于高效的解决多维数组的计算问题。Theano的特点:紧密集成Numpy;高效的数据密集型GPU计算;高效的符号微分运算;高速和稳定的优化;动态生成c代码;广泛的单元测试和自我验证。自2007年以来,Theano已被广泛应用于科学运算。theano使得构建深度学习模型更加容易,可以快速实现多种模型。PS:Theano,一位希腊美女,Croton最有权势的Milo的女儿,后来成为了毕达哥拉斯的老婆。”
12.Pylearn2
Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
“Pylearn2建立在theano上,部分依赖scikit-learn上,目前Pylearn2正处于开发中,将可以处理向量、图像、视频等数据,提供MLP、RBM、SDA等深度学习模型。”
官方主页:
其他的,欢迎大家补充。
欢迎关注“牛衣古柳”
门可罗雀,快来捕鸟!
如何用C/C++写一个基于事件的爬虫
网站优化 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-06-06 17:06
在去年三月份的时候,写过一篇文章,讲了一下如何写一个知乎爬虫,爬下最高票的答案,并且把代码放到了github,。在这一年多的时间里,前前后后有很多人来问我关于这个爬虫的一些实现细节,在回答他们的同时发现自己原来的代码真是写得太烂了,最近正好有空,把代码和架构都重写了一下,不能再误人子弟了。
所以有了这篇文章,记录下自己的一些改进,以及尽可能说清楚如何用C++实现一个高性能爬虫。
为什么要用C++写
在继续往下看之前一定要先想清楚一个问题,现在用Python或者NodeJS可以非常快速地开发出一个爬虫,库齐全,开发成本非常低,那为什么还要用C来写爬虫?答案是这要看你的目的。如果你单纯是为了完成一个数据抓取的任务,当然是任务完成得越快越好,以后代码越好修改越好,首选就是那些库齐全的动态语言,但如果你的目的是为了理解底层系统,理解抓取数据的每一个环节,那么我的推荐是用C++写吧,并且所有轮子都自己造。我的目的是后者,所以选择了用C来写。既然所有轮子都自己造了,那这篇文章应该叫,如何不用任何第三方库,只用C/C++内建函数来完成一个网络爬虫。
用Python写会是什么样子?有Requests库来封装HTTP请求,有BeautifulSoup来解析HTML,大大减少了开发难度,你只需要知道爬虫的一般流程,很容易写出一个能跑的代码,用NodeJS也是一样的。
知乎爬虫原理
如果有读者不太清楚爬虫的原理,请先看一下这篇入门文章。
接下来简单说一个我的zhihu爬虫的原理,因为我的目标是爬下最高赞/最高关注这些类型的答案和问题,所以从用户主页出发是最好不过的,比如从用户主页点击“回答”,就可以看到用户的所有回答,然后抓下来,点击“提问”,就可以看到用户所有的提问。把所有用户的所有回答/提问都抓下来然后根据点赞数/关注数排序,就是我想要的结果。那所有用户怎么得到?从一个用户出发(即队列中的初始URL),把TA的所有关注的人和关注者都爬下来,不重复地放入URL队列中,等到当前用户处理完,再从URL队列里拿下一个用户,如此循环即可。
仔细想想,这个方法会有一个问题,如果一个人即不关注别人也不被别人关注,且不在初始URL队列中,那么这个用户的回答和提问永远不会被抓到。更一般的结论是,如果有用户群构成“孤岛”,那么这些用户群都不会被爬虫访问。举个例子,A、B互相关注,C、D互相关注,如果我们将A放入初始URL队列,那么爬虫只可能抓下A、B的数据,因为C、D构成了“孤岛”,怎么解决这个问题?
再想想,这个问题真的有必要解决吗?这个问题会对我们造成困扰的情况是,一个大V答了一个赞数很高的问题,但是TA竟然在某座“孤岛”上,如果我们称大部分人所构成的连通图叫主图,那么这个大V构成的“孤岛”和主图上的人一点关系都没有,即不被关注也不关注别人,这几乎是不可能的事情,所以这个问题不需要解决。
如何用C++写爬虫
无论用Python或者C++写爬虫,底层都是一样的,都是和server建立若干个TCP连接,然后把HTTP请求写入这个TCP socket中,等待server的数据返回。为了高效处理I/O,在linux平台下需要用epoll(别的平台请用各自的机制)。
所以一个C++爬虫步骤大概是这样的,本质上就是一个事件循环(event loop):
初始化epoll,并和server建立TCP连接
从URL队列中拿出url,并准备好http请求
将http请求写入到这个TCP socket中,并把这个socket加入epoll中
检查活动事件(epoll_wait)
处理事件,读取HTML,解析HTML,处理HTML,然后把相关未处理过的URL放入URL队列中
回到第2步
原来的代码结构
先简单描述一下去年写的爬虫代码是怎么误人子弟的。
程序从队列里拿到一个URL后,需要去下载这个URL的页面,解析出我需要的数据,然后把它的下一层URL加入队列中。原来的爬虫代码就老老实实地实现了这个步骤,阻塞地等待页面下载完成,再去处理这个页面。其实这是很低效的,因为阻塞的这段时期我们什么都干不了,浪费了带宽。为什么不把队列里的其它URL请求一起发出去呢,然后有数据来了我就处理。这就是为什么爬虫为什么要用基于事件来写的原因。
这里需要理解爬虫这种程序的本质,它是网络I/O密集程序,不是CPU密集,而处理I/O密集最高效的做法就是事件循环。
所以我做的一个做大的改善就是把原来的阻塞爬虫改成了基于事件的爬虫,它得到的好处是可以完全把带宽跑满,爬取速度最大化。
除此之外,还有一个改善是把多线程模型改成了单进程模型。有同学可能会产生疑惑,难道利用多核还会比单核性能差?我们从以下两点来分析:
根据amdahl定律,对系统中一个模块的加速,不仅取决于加速比,还取决于这个模块在原来系统中占的比例。爬虫是I/O密集程序,绝大部分时间都花在了网络I/O上,CPU大部分时间是空闲的,所以提高CPU的利用率其实效果很小。
多线程会引入额外的开销,最大的开销可能就是锁了。比如你要把新的URL加入队列,这时候在多线程环境下肯定要对队列加锁。
那么问题就是,第一点所带来的性能提升和第二点所带来的开销,哪个更大一点?如果第二点大,我们果断要换成单进程。答案是看环境,我们极端点看,如果你的带宽无穷大,网络情况无穷好,那么请求一发出去立刻就回复了,这个网络I/O密集程序硬生生变成了CPU密集,多线程会好;如果你的带宽无穷小,那么锁带来的开销会占比更大,一个任务来了多线程之间还要竞争一下,单线程就直接处理了且没有锁的性能开销,用单线程会好。我们需要在不同的环境下选择最好的办法,不过一般来说,现实中最大的时间开销一定在网络I/O。
用C++实现爬虫时的难点
从TCP socket读取数据到把完整的HTML数据交付上层需要一个数据层,因为如果调用read返回EAGAIN时,这时是不知道到底有没有接受到完整的HTML,需要保存好当前读到的网页内容,并通过一个状态机来解析当前收到的数据,保存当前的状态,如果解析完成(读到全部数据了)就返回SUCCESS,否则就就返回ERROR,等待下一次数据来临,继续解析状态机。用动态语言不需要考虑这一点,会直接传递给用户层完整的数据。
请求得太快,知乎会返回429错误(即提示客户请求太多,稍后再试),这个问题怎么解决?乖乖地等待一段时间再去抓是一种浪费带宽的行为。服务器判断请求太多是看这个IP在一段时间的请求数太多了,如果我们IP分散为N个不同IP,那就解决这个问题了。这个方案叫动态IP或者代理IP。那么多IP意味着要花很多的钱,如果不愿意花钱,还是乖乖等一段时间再发请求吧。
爬虫里一个需求,要获得一个用户的所有关注的人和关注者,但这些东西都是通过ajax获取的,所以要写一个post请求来模拟ajax。其中post data里有一个hash_id和_xsrf,这两个值都在哪里可以获得?后来在该用户的主页的HTML里找到了这两个值。
怎么用C++解析HTML?比如上面一点提到的,我要找到这个页面里的hash_id,它可能是某个HTML元素的属性,怎么得到这个属性值?用过JQuery的同学这时会想,如果C++里面也有一个像JQuery那么好用的库该多好,直接写个选择器就获得属性的值了。我简单地调研了一下,C++还是有这样的库的。基于学习的目的,最好自己写一个这样的库,所以,问题来了,怎么实现一个HTML parser?或者更简单的,怎么实现一个正则匹配?
如何管理一个请求的周期,因为一个请求的周期中,状态太多了。为什么状态多,因为一个请求会涉及很多异步操作,首先获取该用户的答案页面,这时候要等待server的回复,处理完以后获得改用户所有关注的人和关注者的页面,也要等待server的回复,再把这些所有用户加入队列后,这个请求周期才算结束。
需要自己处理一些HTTP header的细节。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回复,因为它显然没有Content-length直接获取到数据长度来得方便,该怎么办?再比如不希望接受到gzip处理过的数据,希望收到plain text,又该怎么办?
架构怎么设计。首先最底层是TCP层,上层应该封装一个数据接收层,再上层应该是HTML解析层,最后是事件循环层。这些层次/模块怎么做到耦合度最低?
网络异常怎么处理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一个新的连接,然后继续前一个请求(或者说继续状态机)。
用C++相比Python,NodeJS的优点
系统的掌控性。比如我们希望TCP连接数要控制在1000,完全可能很容易地实现。并且可以知道哪里会耗内存、CPU,底层在发生什么我们更容易知道。比如,在HTTP request header里写上Connection: keep-alive可以让很多请求复用一个TCP连接,在用C++实现的时候,对应的实现方法很简单粗暴:从socket读完对方服务器发来的response后,再构造一个header发过去即可。
因为一些内建库的缺乏,并且出发点是学习,我们会重新造一些轮子,与此同时,提高了编程能力。 比如说读配置文件,格式是json,可以自己用C写个json parser。再比如上文提到的HTML parser,也可以用C写一个,还有基于epoll的事件循环,可以抽象成一个通用的网络库。有太多轮子可以造,要把其中任意一个轮子写好都是非常难的事情。
高性能。可能由于网络的大延迟使得这个优点不那么明显。
总结
本文基于我一年多之前写的zhihu爬虫以及最近的大规模改进,总结了如何用C++编写的高效、基于事件驱动的知乎爬虫,同时也列出了用C++写爬虫时的一些难点与收获。
如果你有兴趣看看竟然有人用C++写了一个爬虫究竟是什么样子的,代码在这里。
. END.
看完本文请分享一下吧!让其他人也可以GET到新知识!
查看全部
如何用C/C++写一个基于事件的爬虫
在去年三月份的时候,写过一篇文章,讲了一下如何写一个知乎爬虫,爬下最高票的答案,并且把代码放到了github,。在这一年多的时间里,前前后后有很多人来问我关于这个爬虫的一些实现细节,在回答他们的同时发现自己原来的代码真是写得太烂了,最近正好有空,把代码和架构都重写了一下,不能再误人子弟了。
所以有了这篇文章,记录下自己的一些改进,以及尽可能说清楚如何用C++实现一个高性能爬虫。
为什么要用C++写
在继续往下看之前一定要先想清楚一个问题,现在用Python或者NodeJS可以非常快速地开发出一个爬虫,库齐全,开发成本非常低,那为什么还要用C来写爬虫?答案是这要看你的目的。如果你单纯是为了完成一个数据抓取的任务,当然是任务完成得越快越好,以后代码越好修改越好,首选就是那些库齐全的动态语言,但如果你的目的是为了理解底层系统,理解抓取数据的每一个环节,那么我的推荐是用C++写吧,并且所有轮子都自己造。我的目的是后者,所以选择了用C来写。既然所有轮子都自己造了,那这篇文章应该叫,如何不用任何第三方库,只用C/C++内建函数来完成一个网络爬虫。
用Python写会是什么样子?有Requests库来封装HTTP请求,有BeautifulSoup来解析HTML,大大减少了开发难度,你只需要知道爬虫的一般流程,很容易写出一个能跑的代码,用NodeJS也是一样的。
知乎爬虫原理
如果有读者不太清楚爬虫的原理,请先看一下这篇入门文章。
接下来简单说一个我的zhihu爬虫的原理,因为我的目标是爬下最高赞/最高关注这些类型的答案和问题,所以从用户主页出发是最好不过的,比如从用户主页点击“回答”,就可以看到用户的所有回答,然后抓下来,点击“提问”,就可以看到用户所有的提问。把所有用户的所有回答/提问都抓下来然后根据点赞数/关注数排序,就是我想要的结果。那所有用户怎么得到?从一个用户出发(即队列中的初始URL),把TA的所有关注的人和关注者都爬下来,不重复地放入URL队列中,等到当前用户处理完,再从URL队列里拿下一个用户,如此循环即可。
仔细想想,这个方法会有一个问题,如果一个人即不关注别人也不被别人关注,且不在初始URL队列中,那么这个用户的回答和提问永远不会被抓到。更一般的结论是,如果有用户群构成“孤岛”,那么这些用户群都不会被爬虫访问。举个例子,A、B互相关注,C、D互相关注,如果我们将A放入初始URL队列,那么爬虫只可能抓下A、B的数据,因为C、D构成了“孤岛”,怎么解决这个问题?
再想想,这个问题真的有必要解决吗?这个问题会对我们造成困扰的情况是,一个大V答了一个赞数很高的问题,但是TA竟然在某座“孤岛”上,如果我们称大部分人所构成的连通图叫主图,那么这个大V构成的“孤岛”和主图上的人一点关系都没有,即不被关注也不关注别人,这几乎是不可能的事情,所以这个问题不需要解决。
如何用C++写爬虫
无论用Python或者C++写爬虫,底层都是一样的,都是和server建立若干个TCP连接,然后把HTTP请求写入这个TCP socket中,等待server的数据返回。为了高效处理I/O,在linux平台下需要用epoll(别的平台请用各自的机制)。
所以一个C++爬虫步骤大概是这样的,本质上就是一个事件循环(event loop):
初始化epoll,并和server建立TCP连接
从URL队列中拿出url,并准备好http请求
将http请求写入到这个TCP socket中,并把这个socket加入epoll中
检查活动事件(epoll_wait)
处理事件,读取HTML,解析HTML,处理HTML,然后把相关未处理过的URL放入URL队列中
回到第2步
原来的代码结构
先简单描述一下去年写的爬虫代码是怎么误人子弟的。
程序从队列里拿到一个URL后,需要去下载这个URL的页面,解析出我需要的数据,然后把它的下一层URL加入队列中。原来的爬虫代码就老老实实地实现了这个步骤,阻塞地等待页面下载完成,再去处理这个页面。其实这是很低效的,因为阻塞的这段时期我们什么都干不了,浪费了带宽。为什么不把队列里的其它URL请求一起发出去呢,然后有数据来了我就处理。这就是为什么爬虫为什么要用基于事件来写的原因。
这里需要理解爬虫这种程序的本质,它是网络I/O密集程序,不是CPU密集,而处理I/O密集最高效的做法就是事件循环。
所以我做的一个做大的改善就是把原来的阻塞爬虫改成了基于事件的爬虫,它得到的好处是可以完全把带宽跑满,爬取速度最大化。
除此之外,还有一个改善是把多线程模型改成了单进程模型。有同学可能会产生疑惑,难道利用多核还会比单核性能差?我们从以下两点来分析:
根据amdahl定律,对系统中一个模块的加速,不仅取决于加速比,还取决于这个模块在原来系统中占的比例。爬虫是I/O密集程序,绝大部分时间都花在了网络I/O上,CPU大部分时间是空闲的,所以提高CPU的利用率其实效果很小。
多线程会引入额外的开销,最大的开销可能就是锁了。比如你要把新的URL加入队列,这时候在多线程环境下肯定要对队列加锁。
那么问题就是,第一点所带来的性能提升和第二点所带来的开销,哪个更大一点?如果第二点大,我们果断要换成单进程。答案是看环境,我们极端点看,如果你的带宽无穷大,网络情况无穷好,那么请求一发出去立刻就回复了,这个网络I/O密集程序硬生生变成了CPU密集,多线程会好;如果你的带宽无穷小,那么锁带来的开销会占比更大,一个任务来了多线程之间还要竞争一下,单线程就直接处理了且没有锁的性能开销,用单线程会好。我们需要在不同的环境下选择最好的办法,不过一般来说,现实中最大的时间开销一定在网络I/O。
用C++实现爬虫时的难点
从TCP socket读取数据到把完整的HTML数据交付上层需要一个数据层,因为如果调用read返回EAGAIN时,这时是不知道到底有没有接受到完整的HTML,需要保存好当前读到的网页内容,并通过一个状态机来解析当前收到的数据,保存当前的状态,如果解析完成(读到全部数据了)就返回SUCCESS,否则就就返回ERROR,等待下一次数据来临,继续解析状态机。用动态语言不需要考虑这一点,会直接传递给用户层完整的数据。
请求得太快,知乎会返回429错误(即提示客户请求太多,稍后再试),这个问题怎么解决?乖乖地等待一段时间再去抓是一种浪费带宽的行为。服务器判断请求太多是看这个IP在一段时间的请求数太多了,如果我们IP分散为N个不同IP,那就解决这个问题了。这个方案叫动态IP或者代理IP。那么多IP意味着要花很多的钱,如果不愿意花钱,还是乖乖等一段时间再发请求吧。
爬虫里一个需求,要获得一个用户的所有关注的人和关注者,但这些东西都是通过ajax获取的,所以要写一个post请求来模拟ajax。其中post data里有一个hash_id和_xsrf,这两个值都在哪里可以获得?后来在该用户的主页的HTML里找到了这两个值。
怎么用C++解析HTML?比如上面一点提到的,我要找到这个页面里的hash_id,它可能是某个HTML元素的属性,怎么得到这个属性值?用过JQuery的同学这时会想,如果C++里面也有一个像JQuery那么好用的库该多好,直接写个选择器就获得属性的值了。我简单地调研了一下,C++还是有这样的库的。基于学习的目的,最好自己写一个这样的库,所以,问题来了,怎么实现一个HTML parser?或者更简单的,怎么实现一个正则匹配?
如何管理一个请求的周期,因为一个请求的周期中,状态太多了。为什么状态多,因为一个请求会涉及很多异步操作,首先获取该用户的答案页面,这时候要等待server的回复,处理完以后获得改用户所有关注的人和关注者的页面,也要等待server的回复,再把这些所有用户加入队列后,这个请求周期才算结束。
需要自己处理一些HTTP header的细节。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回复,因为它显然没有Content-length直接获取到数据长度来得方便,该怎么办?再比如不希望接受到gzip处理过的数据,希望收到plain text,又该怎么办?
架构怎么设计。首先最底层是TCP层,上层应该封装一个数据接收层,再上层应该是HTML解析层,最后是事件循环层。这些层次/模块怎么做到耦合度最低?
网络异常怎么处理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一个新的连接,然后继续前一个请求(或者说继续状态机)。
用C++相比Python,NodeJS的优点
系统的掌控性。比如我们希望TCP连接数要控制在1000,完全可能很容易地实现。并且可以知道哪里会耗内存、CPU,底层在发生什么我们更容易知道。比如,在HTTP request header里写上Connection: keep-alive可以让很多请求复用一个TCP连接,在用C++实现的时候,对应的实现方法很简单粗暴:从socket读完对方服务器发来的response后,再构造一个header发过去即可。
因为一些内建库的缺乏,并且出发点是学习,我们会重新造一些轮子,与此同时,提高了编程能力。 比如说读配置文件,格式是json,可以自己用C写个json parser。再比如上文提到的HTML parser,也可以用C写一个,还有基于epoll的事件循环,可以抽象成一个通用的网络库。有太多轮子可以造,要把其中任意一个轮子写好都是非常难的事情。
高性能。可能由于网络的大延迟使得这个优点不那么明显。
总结
本文基于我一年多之前写的zhihu爬虫以及最近的大规模改进,总结了如何用C++编写的高效、基于事件驱动的知乎爬虫,同时也列出了用C++写爬虫时的一些难点与收获。
如果你有兴趣看看竟然有人用C++写了一个爬虫究竟是什么样子的,代码在这里。
. END.
看完本文请分享一下吧!让其他人也可以GET到新知识!

网站将用户资料分门别类的存储在百度中
网站优化 • 优采云 发表了文章 • 0 个评论 • 72 次浏览 • 2022-06-05 16:01
c爬虫抓取网页数据,可以得到我们想要的各种格式的数据用户信息是可以作为数据有价值的获取来源。比如一个网站将用户资料分门别类的存储在百度中,那么用户不仅可以接受百度的url信息,还可以查看百度收录了哪些对自己有用的用户信息。根据产品上线的数据质量对用户信息的价值进行确定,在这里对用户信息的价值分为初级价值、中级价值、高级价值三类(根据产品和相关业务流程的特征进行下划分),初级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看新推荐的商品、查看优惠券的使用情况中级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看优惠券的使用情况高级价值比如某宝同城生活服务平台的用户在微信上获取到完整图片视频等内容的用户信息通过以上的分类,一般可以根据产品的定位将用户信息划分出来,放到哪里去获取都可以。info_data_name。
根据业务特征选择,设计合理的信息模型和链路,及时对信息进行处理对网页中的信息进行解析,提取信息特征,并储存起来需要获取什么样的信息信息以数据库的形式存储即可,没有特定指标来要求储存速度,txt或者json,提取关键字,把抽象内容链接到一起即可,最重要的是全量的准确性,保证准确性的一点是有足够快的读写速度。
对于广告业务而言,定制特征是非常重要的,比如有的广告有固定的位置标识、pagerank、ctr特征等等,然后如果参与定制特征的平台多,定制特征的粒度够细的话,本地数据库的使用率会比较低对数据进行分类管理,类似etl,用一定的算法和策略将所有的存储到不同数据库中去如果需要进行分析,可以自己对业务、流程进行重构,比如:消息队列,过滤流程,负载均衡等等,将不同的业务特征,流程拆分成不同粒度的数据仓库。 查看全部
网站将用户资料分门别类的存储在百度中
c爬虫抓取网页数据,可以得到我们想要的各种格式的数据用户信息是可以作为数据有价值的获取来源。比如一个网站将用户资料分门别类的存储在百度中,那么用户不仅可以接受百度的url信息,还可以查看百度收录了哪些对自己有用的用户信息。根据产品上线的数据质量对用户信息的价值进行确定,在这里对用户信息的价值分为初级价值、中级价值、高级价值三类(根据产品和相关业务流程的特征进行下划分),初级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看新推荐的商品、查看优惠券的使用情况中级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看优惠券的使用情况高级价值比如某宝同城生活服务平台的用户在微信上获取到完整图片视频等内容的用户信息通过以上的分类,一般可以根据产品的定位将用户信息划分出来,放到哪里去获取都可以。info_data_name。
根据业务特征选择,设计合理的信息模型和链路,及时对信息进行处理对网页中的信息进行解析,提取信息特征,并储存起来需要获取什么样的信息信息以数据库的形式存储即可,没有特定指标来要求储存速度,txt或者json,提取关键字,把抽象内容链接到一起即可,最重要的是全量的准确性,保证准确性的一点是有足够快的读写速度。
对于广告业务而言,定制特征是非常重要的,比如有的广告有固定的位置标识、pagerank、ctr特征等等,然后如果参与定制特征的平台多,定制特征的粒度够细的话,本地数据库的使用率会比较低对数据进行分类管理,类似etl,用一定的算法和策略将所有的存储到不同数据库中去如果需要进行分析,可以自己对业务、流程进行重构,比如:消息队列,过滤流程,负载均衡等等,将不同的业务特征,流程拆分成不同粒度的数据仓库。
如何构建一个分布式爬虫:实战篇
网站优化 • 优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2022-06-05 05:09
种子博主具体信息
这里我们就看到了他的具体信息了。然后,我们看该页面的 url 构造
我直接 copy 的地址栏的 url。这样做有啥不好的呢?对于老鸟来说,一下就看出来了,这样做的话,可能会导致信息不全,因为可能有些信息是动态加载的。所以,我们需要通过抓包来判断到底微博会通过该 url 返回所有信息,还是需要请求一些 ajax 链接才会返回一些关键信息。这里我就重复一下我的观点:抓包很重要,抓包很重要,抓包很重要!重要的事情说三遍。关于抓包,我在模拟登陆微博和模拟登陆百度云都详细讲过了,这里我就不讲了。
我们抓完包,发现并没有 ajax 请求。那么可以肯定请求前面的 url,会返回所有信息。我们通过点击鼠标右键,查看网页源代码,然后ctrl a、ctrl c将所有的页面源码保存到本地,这里我命名为personinfo.html。我们用浏览器打开该文件,发现我们需要的所有信息都在这段源码中,这个工作和抓包判断数据是否全面有些重复,但是在我看来是必不可少的,因为我们解析页面数据的时候还可以用到这个 html 文件,如果我们每次都通过网络请求去解析内容的话,那么可能账号没一会儿就会被封了(因为频繁访问微博信息),所以我们需要把要解析的文件保存到本地。
从上面分析中我们可以得知
这个 url 就是获取用户数据的 url。那么我们在只知道用户 id 的时候怎么构造它呢?我们可以多拿几个用户 id 来做测试,看构造是否有规律,比如我这里以用户名为网易云音乐的用户做分析,发现它的用户信息页面构造如下
这个就和上面那个不同了。但是我们仔细观察,可以发现上面那个是个人用户,下面是企业微博用户。我们尝试一下把它们 url 格式都统一为第一种或者第二种的格式
这样会出现 404,那么统一成上面那种呢?
这样子的话,它会被重定向到用户主页,而不是用户详细资料页。所以也就不对了。那么该以什么依据判断何时用第一种 url 格式,何时用第二种 url 格式呢?我们多翻几个用户,会发现除了100505之外,还有100305、100206等前缀,那么我猜想这个应该可以区分不同用户。这个前缀在哪里可以得到呢?我们打开我们刚保存的页面源码,搜索100505,可以发现
domain
微博应该是根据这个来区分不同用户类型的。这里大家可以自己也可以试试,看不同用户的domain是否不同。为了数据能全面,我也是做了大量测试,发现个人用户的 domain 是1005051,作家是100305,其他基本都是认证的企业号。前两个个人信息的 url 构造就是
后者的是
弄清楚了个人信息 url 的构造方式,但是还有一个问题。我们已知只有 uid 啊,没有 domain 啊。如果是企业号,我们通过domain=100505会被重定向到主页,如果是作家等(domain=100305 或者 100306),也会被重定向主页。我们在主页把 domain 提取出来,再请求一次,不就能拿到用户详细信息了吗?
关于如何构造获取用户信息的 url 的相关分析就到这里了。因为我们是在登录的情况下进行数据抓取的,可能在抓取的时候,某个账号突然就被封了,或者由于网络原因,某次请求失败了,该如何处理?对于前者,我们需要判断每次请求返回的内容是否符合预期,也就是看 response url 是否正常,看 response content 是否是 404 或者让你验证手机号等,对于后者,我们可以做一个简单的重试策略,大概代码如下
<p>@timeout_decorator
def get_page(url, user_verify=True, need_login=True):
"""
:param url: 待抓取 url
:param user_verify: 是否为可能出现验证码的页面(ajax 连接不会出现验证码,如果是请求微博或者用户信息可能出现验证码),否为抓取转发的 ajax 连接
:param need_login: 抓取页面是否需要登录,这样做可以减小一些账号的压力
:return: 返回请求的数据,如果出现 404 或者 403,或者是别的异常,都返回空字符串
"""
crawler.info('本次抓取的 url 为{url}'.format(url=url))
count = 0<p> while count 查看全部
如何构建一个分布式爬虫:实战篇
种子博主具体信息
这里我们就看到了他的具体信息了。然后,我们看该页面的 url 构造
我直接 copy 的地址栏的 url。这样做有啥不好的呢?对于老鸟来说,一下就看出来了,这样做的话,可能会导致信息不全,因为可能有些信息是动态加载的。所以,我们需要通过抓包来判断到底微博会通过该 url 返回所有信息,还是需要请求一些 ajax 链接才会返回一些关键信息。这里我就重复一下我的观点:抓包很重要,抓包很重要,抓包很重要!重要的事情说三遍。关于抓包,我在模拟登陆微博和模拟登陆百度云都详细讲过了,这里我就不讲了。
我们抓完包,发现并没有 ajax 请求。那么可以肯定请求前面的 url,会返回所有信息。我们通过点击鼠标右键,查看网页源代码,然后ctrl a、ctrl c将所有的页面源码保存到本地,这里我命名为personinfo.html。我们用浏览器打开该文件,发现我们需要的所有信息都在这段源码中,这个工作和抓包判断数据是否全面有些重复,但是在我看来是必不可少的,因为我们解析页面数据的时候还可以用到这个 html 文件,如果我们每次都通过网络请求去解析内容的话,那么可能账号没一会儿就会被封了(因为频繁访问微博信息),所以我们需要把要解析的文件保存到本地。
从上面分析中我们可以得知
这个 url 就是获取用户数据的 url。那么我们在只知道用户 id 的时候怎么构造它呢?我们可以多拿几个用户 id 来做测试,看构造是否有规律,比如我这里以用户名为网易云音乐的用户做分析,发现它的用户信息页面构造如下
这个就和上面那个不同了。但是我们仔细观察,可以发现上面那个是个人用户,下面是企业微博用户。我们尝试一下把它们 url 格式都统一为第一种或者第二种的格式
这样会出现 404,那么统一成上面那种呢?
这样子的话,它会被重定向到用户主页,而不是用户详细资料页。所以也就不对了。那么该以什么依据判断何时用第一种 url 格式,何时用第二种 url 格式呢?我们多翻几个用户,会发现除了100505之外,还有100305、100206等前缀,那么我猜想这个应该可以区分不同用户。这个前缀在哪里可以得到呢?我们打开我们刚保存的页面源码,搜索100505,可以发现
domain
微博应该是根据这个来区分不同用户类型的。这里大家可以自己也可以试试,看不同用户的domain是否不同。为了数据能全面,我也是做了大量测试,发现个人用户的 domain 是1005051,作家是100305,其他基本都是认证的企业号。前两个个人信息的 url 构造就是
后者的是
弄清楚了个人信息 url 的构造方式,但是还有一个问题。我们已知只有 uid 啊,没有 domain 啊。如果是企业号,我们通过domain=100505会被重定向到主页,如果是作家等(domain=100305 或者 100306),也会被重定向主页。我们在主页把 domain 提取出来,再请求一次,不就能拿到用户详细信息了吗?
关于如何构造获取用户信息的 url 的相关分析就到这里了。因为我们是在登录的情况下进行数据抓取的,可能在抓取的时候,某个账号突然就被封了,或者由于网络原因,某次请求失败了,该如何处理?对于前者,我们需要判断每次请求返回的内容是否符合预期,也就是看 response url 是否正常,看 response content 是否是 404 或者让你验证手机号等,对于后者,我们可以做一个简单的重试策略,大概代码如下
<p>@timeout_decorator
def get_page(url, user_verify=True, need_login=True):
"""
:param url: 待抓取 url
:param user_verify: 是否为可能出现验证码的页面(ajax 连接不会出现验证码,如果是请求微博或者用户信息可能出现验证码),否为抓取转发的 ajax 连接
:param need_login: 抓取页面是否需要登录,这样做可以减小一些账号的压力
:return: 返回请求的数据,如果出现 404 或者 403,或者是别的异常,都返回空字符串
"""
crawler.info('本次抓取的 url 为{url}'.format(url=url))
count = 0<p> while count
微博各种数据抓取思路与难点总结——小白爬虫进阶(1)
网站优化 • 优采云 发表了文章 • 0 个评论 • 304 次浏览 • 2022-06-04 11:43
最近后台留言异常的多,还有不少催更,看来各位小伙伴都是寒假稍歇后就立刻又投身于秃头事业了,让大家久等了,2022一起继续加油。
在之前的小白爬虫实战(1)里,我们以马云的微博为例初步演示了如何爬取一个微博用户的所有微博文本(回顾戳这→),最近有很多同学后台问起详细的思路,也有小伙伴对如何进一步抓取微博转发、评论、点赞数据甚至配图的抓取方法提出了疑问。
针对以上问题,本篇对微博数据的抓取做一个专门的梳理与总结,本文分为以下三部分:
1、抓取URL的构造
2、微博文本、转发、评论、点赞数据的抓取与保存
3、微博图片的抓取与保存
经过这三部分的梳理,相信各位能对有关微博的抓取有更进一步的了解,无论是抓取话题还是抓取热搜,万变不离其宗,只需要按需求在本文基础上进行些改动即可。
注意:本篇是基于爬虫实战(1)等前面相关内容之上的总结,一些基础的内容便不再赘述,有需要的小伙伴可以回顾之前的相关内容:
下面我们开始这三部分——
1
抓取URL的构造
在爬虫实战(1)中,我们用检查中的XHR过滤器找到了获取数据所需的链接地址,这个链接地址有一大坨,第一页链接与之后链接的差距就在于第一页的链接尾部没有since_id参数,这次我们进一步对这一大坨链接进行分解分析。
%3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
上面即是马云微博数据的第二页链接,若是把链接末尾的since_id删去即为第一页链接。在这么一大坨链接里,最终是靠着末尾since_id的变化实现获取下一页数据的,在爬虫实战(1)中,我们是直接将这一大坨复制粘贴到代码中,而为since_id专门设了一个变量,这次我们再进一步将这个链接拆分看看。
实际上,这么一大坨连接中,只有
为基础连接,后面的一长串都是各种各样的参数组合,比如uid、t、luicode等等,而这一长串由百分号、数字和字母构成的部分我们可以通过解码得到它的实际文本
%3D1%26q%3D%E9%A9%AC%E4%BA%91
我们可以在中对上面这行奇奇怪怪的内容进行URL解码:
解码之后:
通过解码可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的实际文本含义为“=1&q=马云”,据此可得这一大串链接的真实表达为:
=1&q=马云&type=uid&value=2145291155&containerid=91155&since_id=44903
也就是一个基础链接加上各种必要参数的组合。在Python中我们可以通过调用urlencode()方法将构造的参数字典与基础连接组合生成完整链接,据此我们首先构造一个生成完整请求链接的函数:
from urllib.parse import urlencode
def generate_url(since_id='0'):
"""
构造完整链接 """
base_url = ''
params = {
'uid': '2145291155',
't': '0',
'luicode': '10000011',
'lfid': '100103type=1',
'q': '马云',
'type': 'uid',
'value': '2145291155',
'containerid': '91155',
'since_id': since_id
}
url = base_url + urlencode(params)
return url
generate_url
因为只有since_id是变化的,而第一页链接又不含since_id,所以这里设一个since_id默认值为0的变量。
到此,抓取所需的URL便构造完成了。
2
微博文本、转发、评论、点赞数据的抓取与保存
在爬虫实战(1)中说到,若用火狐浏览器访问我们所构造的URL,可以得到结构化的json数据,而我们所需要抓取的目标就在这些json数据之中。微博文本在mblog的text下,而转发、评论、点赞数据也异曲同工:
数据位置
数据含义
mblog→reposts_count
点赞数
mblog→comments_count 查看全部
微博各种数据抓取思路与难点总结——小白爬虫进阶(1)
最近后台留言异常的多,还有不少催更,看来各位小伙伴都是寒假稍歇后就立刻又投身于秃头事业了,让大家久等了,2022一起继续加油。
在之前的小白爬虫实战(1)里,我们以马云的微博为例初步演示了如何爬取一个微博用户的所有微博文本(回顾戳这→),最近有很多同学后台问起详细的思路,也有小伙伴对如何进一步抓取微博转发、评论、点赞数据甚至配图的抓取方法提出了疑问。
针对以上问题,本篇对微博数据的抓取做一个专门的梳理与总结,本文分为以下三部分:
1、抓取URL的构造
2、微博文本、转发、评论、点赞数据的抓取与保存
3、微博图片的抓取与保存
经过这三部分的梳理,相信各位能对有关微博的抓取有更进一步的了解,无论是抓取话题还是抓取热搜,万变不离其宗,只需要按需求在本文基础上进行些改动即可。
注意:本篇是基于爬虫实战(1)等前面相关内容之上的总结,一些基础的内容便不再赘述,有需要的小伙伴可以回顾之前的相关内容:
下面我们开始这三部分——
1
抓取URL的构造
在爬虫实战(1)中,我们用检查中的XHR过滤器找到了获取数据所需的链接地址,这个链接地址有一大坨,第一页链接与之后链接的差距就在于第一页的链接尾部没有since_id参数,这次我们进一步对这一大坨链接进行分解分析。
%3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
上面即是马云微博数据的第二页链接,若是把链接末尾的since_id删去即为第一页链接。在这么一大坨链接里,最终是靠着末尾since_id的变化实现获取下一页数据的,在爬虫实战(1)中,我们是直接将这一大坨复制粘贴到代码中,而为since_id专门设了一个变量,这次我们再进一步将这个链接拆分看看。
实际上,这么一大坨连接中,只有
为基础连接,后面的一长串都是各种各样的参数组合,比如uid、t、luicode等等,而这一长串由百分号、数字和字母构成的部分我们可以通过解码得到它的实际文本
%3D1%26q%3D%E9%A9%AC%E4%BA%91
我们可以在中对上面这行奇奇怪怪的内容进行URL解码:
解码之后:
通过解码可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的实际文本含义为“=1&q=马云”,据此可得这一大串链接的真实表达为:
=1&q=马云&type=uid&value=2145291155&containerid=91155&since_id=44903
也就是一个基础链接加上各种必要参数的组合。在Python中我们可以通过调用urlencode()方法将构造的参数字典与基础连接组合生成完整链接,据此我们首先构造一个生成完整请求链接的函数:
from urllib.parse import urlencode
def generate_url(since_id='0'):
"""
构造完整链接 """
base_url = ''
params = {
'uid': '2145291155',
't': '0',
'luicode': '10000011',
'lfid': '100103type=1',
'q': '马云',
'type': 'uid',
'value': '2145291155',
'containerid': '91155',
'since_id': since_id
}
url = base_url + urlencode(params)
return url
generate_url
因为只有since_id是变化的,而第一页链接又不含since_id,所以这里设一个since_id默认值为0的变量。
到此,抓取所需的URL便构造完成了。
2
微博文本、转发、评论、点赞数据的抓取与保存
在爬虫实战(1)中说到,若用火狐浏览器访问我们所构造的URL,可以得到结构化的json数据,而我们所需要抓取的目标就在这些json数据之中。微博文本在mblog的text下,而转发、评论、点赞数据也异曲同工:
数据位置
数据含义
mblog→reposts_count
点赞数
mblog→comments_count
Python爬虫入门,8个常用爬虫技巧盘点
网站优化 • 优采云 发表了文章 • 0 个评论 • 136 次浏览 • 2022-06-04 06:47
5、页面解析
对于页面解析最强大的当然是正则表达式,
这个对于不同网站不同的使用者都不一样,就不用过多的说明。
其次就是解析库了,常用的有两个lxml和BeautifulSoup。
对于这两个库,我的评价是,
都是HTML/XML的处理库,Beautifulsoup纯python实现,效率低,
但是功能实用,比如能用通过结果搜索获得某个HTML节点的源码;
lxmlC语言编码,高效,支持Xpath。
6.验证码的处理
碰到验证码咋办?
这里分两种情况处理:
google那种验证码,没办法。
简单的验证码:字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,
这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,
然后划分单个字符,划分好了以后再通过特征提取的方法(例如PCA)降维并生成特征库,
然后把验证码和特征库进行比较。
这个比较复杂,这里就不展开了,
具体做法请弄本相关教科书好好研究一下。
7. gzip/deflate支持
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,
以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。
这就意味着抓取速度会快5倍。
然而python的urllib/urllib2默认都不支持压缩
要返回压缩格式,必须在request的header里面写明’accept-encoding’,
然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。
如何让urllib2自动支持gzip, defalte呢?
其实可以继承BaseHanlder类,
然后build_opener的方式来处理:
8、多线程并发抓取
单线程太慢的话,就需要多线程了,
这里给个简单的线程池模板 这个程序只是简单地打印了1-10,
但是可以看出是并发的。
虽然说Python的多线程很鸡肋
但是对于爬虫这种网络频繁型,
还是能一定程度提高效率的。
9. 总结
阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身。
Python虽然是基于C语言编写,但是摒弃了C中复杂的指针,使其变得简明易学。
并且作为开源软件,Python允许对代码进行阅读,拷贝甚至改进。
这些性能成就了Python的高效率,有“人生苦短,我用Python”之说,是一种十分精彩又强大的语言。
总而言之,开始学Python一定要注意这4点:
1.代码规范,这本身就是一个非常好的习惯,如果开始不养好好的代码规划,以后会很痛苦。
2.多动手,少看书,很多人学Python就一味的看书,这不是学数学物理,你看例题可能就会了,学习Python主要是学习编程思想。
3.勤练习,学完新的知识点,一定要记得如何去应用,不然学完就会忘,学我们这行主要都是实际操作。
4.学习要有效率,如果自己都觉得效率非常低,那就停不停,找一下原因,去问问过来人这是为什么。
推荐↓↓↓
长
按
关
注
【】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。 查看全部
Python爬虫入门,8个常用爬虫技巧盘点
5、页面解析
对于页面解析最强大的当然是正则表达式,
这个对于不同网站不同的使用者都不一样,就不用过多的说明。
其次就是解析库了,常用的有两个lxml和BeautifulSoup。
对于这两个库,我的评价是,
都是HTML/XML的处理库,Beautifulsoup纯python实现,效率低,
但是功能实用,比如能用通过结果搜索获得某个HTML节点的源码;
lxmlC语言编码,高效,支持Xpath。
6.验证码的处理
碰到验证码咋办?
这里分两种情况处理:
google那种验证码,没办法。
简单的验证码:字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,
这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,
然后划分单个字符,划分好了以后再通过特征提取的方法(例如PCA)降维并生成特征库,
然后把验证码和特征库进行比较。
这个比较复杂,这里就不展开了,
具体做法请弄本相关教科书好好研究一下。
7. gzip/deflate支持
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,
以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。
这就意味着抓取速度会快5倍。
然而python的urllib/urllib2默认都不支持压缩
要返回压缩格式,必须在request的header里面写明’accept-encoding’,
然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。
如何让urllib2自动支持gzip, defalte呢?
其实可以继承BaseHanlder类,
然后build_opener的方式来处理:
8、多线程并发抓取
单线程太慢的话,就需要多线程了,
这里给个简单的线程池模板 这个程序只是简单地打印了1-10,
但是可以看出是并发的。
虽然说Python的多线程很鸡肋
但是对于爬虫这种网络频繁型,
还是能一定程度提高效率的。
9. 总结
阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身。
Python虽然是基于C语言编写,但是摒弃了C中复杂的指针,使其变得简明易学。
并且作为开源软件,Python允许对代码进行阅读,拷贝甚至改进。
这些性能成就了Python的高效率,有“人生苦短,我用Python”之说,是一种十分精彩又强大的语言。
总而言之,开始学Python一定要注意这4点:
1.代码规范,这本身就是一个非常好的习惯,如果开始不养好好的代码规划,以后会很痛苦。
2.多动手,少看书,很多人学Python就一味的看书,这不是学数学物理,你看例题可能就会了,学习Python主要是学习编程思想。
3.勤练习,学完新的知识点,一定要记得如何去应用,不然学完就会忘,学我们这行主要都是实际操作。
4.学习要有效率,如果自己都觉得效率非常低,那就停不停,找一下原因,去问问过来人这是为什么。
推荐↓↓↓
长
按
关
注
【】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。
实战演练——爱婴医院中莆田系医院数据分析(一)
网站优化 • 优采云 发表了文章 • 0 个评论 • 67 次浏览 • 2022-06-04 06:44
技术总编:张 邯
爬虫俱乐部将于2020年1月5日至11日在湖北武汉举行为期一周的Stata编程技术定制培训,此次采取初级班和高级班分批次培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata软件编程、金融计量知识和实证分析方法,使大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。目前正在火热招生中~详细培训大纲及报名方式,请点击《》或点击文末阅读原文呦~
自2015年党的十八届五中全会开放二孩政策实施以来,越来越多天真可爱的孩子在这个中国特色社会新时代呱呱坠地。但是,“7岁男童坠楼身亡”、“幼儿园虐童”等新闻时时刻刻提醒我们,要全方位、多角度对这些祖国未来的建设者进行保护。当然,保护他们要从保护他们的出生做起。
开放二孩政策实施后,国家妇幼健康司响应号召,在2015年11月公布了《国家卫生计生委关于公布全国爱婴医院名单的公告》,旨在“不断改善产科儿科服务质量,逐步提高母乳喂养率,降低非医学指征剖宫产率,保障调整完善生育政策顺利实施”。(网址:)
当小编打开这些名单浏览的时候,这里面有些医院的名字竟形同“莆田系医院”,为了识别这其中为数不多的“莆田系医院”,小编决定使用Python来一探究竟。
由于篇幅限制,本篇重点介绍如何获取所需的.docx文件,下篇重点介绍如何提取.docx文件中的表格信息并与已有的数据库进行匹配。
本文涉及的技术要点:
①获取公告附件②获取word文件中的表格信息③ 将.doc文件转换为.docx文件
一、使用网络爬虫技术抓取爱婴医院名单
1、创建文件夹并改变缺省路径
导入Python的os标准库,判断是否存在我们需要的文件夹,如果不存在则创建,将新创建的文件夹作为缺省路径,程序如下:
import osif not os.path.exists(r"D:/爱婴医院"): os.mkdir(r"D:/爱婴医院")os.chdir(r"D:/爱婴医院")
2、导入requests标准库和re标准库抓取WORD文件
requests和re库的使用在爬虫俱乐部往期推文《》和《》中已详细介绍。首先,导入标准库,构造headers,并抓取网页源代码,程序如下:
import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字节码再转换为字符串,避免乱码。print(text)
结果如下:
可见,我们使用requests库成功将网页源代码抓取下来。源代码中存有WORD文件的URL,我们将其中一个复制下来进行分析:
<A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市爱婴医院名单.doc</A></P>
其中的URL可以使用正则表达式A[ ]target.*?href="(.*?)"进行提取,我们提取出32个WORD文件的URL并放在一个列表中,程序如下:
urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
结果如下:
最后,使用requests库,根据列表中的URL下载WORD文件,程序如下:
for nu,c in enumerate(c_url): co = requests.get(c) #获取文件 suffix = os.path.splitext(c)[1] #分离文件名与文件后缀(.doc或.docx) filename = str(nu)+suffix #用序号给文件命名,生成新的文件名 with open(filename,'wb') as f: f.write(co.content)
此时,在缺省路径中就出现了我们需要的WORD文件,结果如下:
二、将.doc文件转换为.docx文件
由于Python无法读取.doc文件,因此我们先将.doc转换为.docx。
导入标准库并定义转化函数:
from win32com import client# win32com.client可以直接调用VBA的库,对Word、Excel进行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打开word。 doc = word.Documents.Open(path) # 打开目标路径下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close() word.Quit() #退出
上述函数需要传入文件名。接下来定义一个函数,用来将指定文件夹中的所有文件存入历列表中:
def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路径, 将多个路径组合后返回 if os.path.isdir(i): #用于判断某一对象是否为目录 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i) return file_list
调用上述函数进行转换并删掉.doc文件,程序如下:
dir_path = "D:\爱婴医院" #批量转换文件夹ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#删掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc": os.remove(c)
结果如下:
此时,文件就全部转换为了.docx文件。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。投稿邮箱:投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。
查看全部
实战演练——爱婴医院中莆田系医院数据分析(一)
技术总编:张 邯
爬虫俱乐部将于2020年1月5日至11日在湖北武汉举行为期一周的Stata编程技术定制培训,此次采取初级班和高级班分批次培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata软件编程、金融计量知识和实证分析方法,使大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。目前正在火热招生中~详细培训大纲及报名方式,请点击《》或点击文末阅读原文呦~
自2015年党的十八届五中全会开放二孩政策实施以来,越来越多天真可爱的孩子在这个中国特色社会新时代呱呱坠地。但是,“7岁男童坠楼身亡”、“幼儿园虐童”等新闻时时刻刻提醒我们,要全方位、多角度对这些祖国未来的建设者进行保护。当然,保护他们要从保护他们的出生做起。
开放二孩政策实施后,国家妇幼健康司响应号召,在2015年11月公布了《国家卫生计生委关于公布全国爱婴医院名单的公告》,旨在“不断改善产科儿科服务质量,逐步提高母乳喂养率,降低非医学指征剖宫产率,保障调整完善生育政策顺利实施”。(网址:)
当小编打开这些名单浏览的时候,这里面有些医院的名字竟形同“莆田系医院”,为了识别这其中为数不多的“莆田系医院”,小编决定使用Python来一探究竟。
由于篇幅限制,本篇重点介绍如何获取所需的.docx文件,下篇重点介绍如何提取.docx文件中的表格信息并与已有的数据库进行匹配。
本文涉及的技术要点:
①获取公告附件②获取word文件中的表格信息③ 将.doc文件转换为.docx文件
一、使用网络爬虫技术抓取爱婴医院名单
1、创建文件夹并改变缺省路径
导入Python的os标准库,判断是否存在我们需要的文件夹,如果不存在则创建,将新创建的文件夹作为缺省路径,程序如下:
import osif not os.path.exists(r"D:/爱婴医院"): os.mkdir(r"D:/爱婴医院")os.chdir(r"D:/爱婴医院")
2、导入requests标准库和re标准库抓取WORD文件
requests和re库的使用在爬虫俱乐部往期推文《》和《》中已详细介绍。首先,导入标准库,构造headers,并抓取网页源代码,程序如下:
import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字节码再转换为字符串,避免乱码。print(text)
结果如下:
可见,我们使用requests库成功将网页源代码抓取下来。源代码中存有WORD文件的URL,我们将其中一个复制下来进行分析:
<A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市爱婴医院名单.doc</A></P>
其中的URL可以使用正则表达式A[ ]target.*?href="(.*?)"进行提取,我们提取出32个WORD文件的URL并放在一个列表中,程序如下:
urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
结果如下:
最后,使用requests库,根据列表中的URL下载WORD文件,程序如下:
for nu,c in enumerate(c_url): co = requests.get(c) #获取文件 suffix = os.path.splitext(c)[1] #分离文件名与文件后缀(.doc或.docx) filename = str(nu)+suffix #用序号给文件命名,生成新的文件名 with open(filename,'wb') as f: f.write(co.content)
此时,在缺省路径中就出现了我们需要的WORD文件,结果如下:
二、将.doc文件转换为.docx文件
由于Python无法读取.doc文件,因此我们先将.doc转换为.docx。
导入标准库并定义转化函数:
from win32com import client# win32com.client可以直接调用VBA的库,对Word、Excel进行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打开word。 doc = word.Documents.Open(path) # 打开目标路径下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close() word.Quit() #退出
上述函数需要传入文件名。接下来定义一个函数,用来将指定文件夹中的所有文件存入历列表中:
def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路径, 将多个路径组合后返回 if os.path.isdir(i): #用于判断某一对象是否为目录 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i) return file_list
调用上述函数进行转换并删掉.doc文件,程序如下:
dir_path = "D:\爱婴医院" #批量转换文件夹ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#删掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc": os.remove(c)
结果如下:
此时,文件就全部转换为了.docx文件。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。投稿邮箱:投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。
小白学 Python 爬虫(42):春节去哪里玩(系列终篇)
网站优化 • 优采云 发表了文章 • 0 个评论 • 186 次浏览 • 2022-05-26 12:39
人生苦短,我用 Python
前文传送门:
引言
首先恭喜看到这篇文章的同学,本篇内容为 「小白学 Python 爬虫」 系列的最后一篇。
看了下上面的前文传送门,加上这篇内容,总共有 42 篇,小编还是成就感满满,小编翻看了下公众号,第一篇文章是在 2019 年的 11 月 17 日推送的,大致数了数,将近两个月的时间。
当然,其中一些文章的质量并不高,很多都是在比较有限的时间中赶工赶出来的,还是感谢各位读者对小编的不离不弃,写的这么烂还没取关的绝对是真爱了。
正好下周就要过年了,从推送的时间算的话还有 10 个自然日左右的时间,可能很多同学可能过年是要出去玩的,那么去哪里玩就成了一个问题。
那么,怎么挑选去哪里玩最快的,小编想了想,直接去抓某站的数据吧,抓下来自己根据自己的情况查询下就好了。
那么今天的目标站是:马蜂窝。
这里小编还想说一点,虽然我们在前面 7、 8 篇文章中都是在讲如何使用爬虫框架 Scrapy ,说实话,小编并不觉得 Scrapy 有多方便,在一些简单的应用场景下,使用 Requests 库可能是最方便的选择, Scrapy 小编个人感觉还是更适合使用在一些中大型的爬虫项目中,简单的爬虫脚本使用最简单的技术栈就 ok 了,所以小编在本文中使用的技术栈还是 Requests + PyQuery 。
不要问为啥,问就是喜欢。
分析
首先我们访问链接,打开我们将要抓取的站点:。
这里是攻略的列表页,我们的目标是抓取来自游记的数据,其余的数据放过,原因是在游记中我们才能获取到一些具体的我们需要的数据。
数据的来源搞清楚了,接下来是翻页功能,只有清楚了如何翻页,我们才能源源不断的获取数据,否则就只能抓取第一页的数据了。
当把页面翻到最下面的时候就尴尬了,发现是自动加载更多,这个当然难不倒帅气逼人的小编我,掏出大杀器, Chrome 的开发者工具 F12 ,选到 network 标签页,再往下滚动一下,我们查看下这个页面发出的请求。
这个请求很有意思,请求的路径和我们访问的页面路径一样,但是请求类型变成 POST ,并且增加了请求参数,类型还是 Form 表单格式的。
截止这里,我们已经清楚了目标站点的数据路径以及翻页方式,虽然目前我们并不知道最大页数是多少,但是我们可以人为的设置一个最大页数,比如 100 或者 200 ,小编相信,这么大的站点上,几百页的游记应该是还有的。
代码
代码小编就直接贴出来,之前有同学希望数据是保存在 Excel 中的,本次实战的数据就不存数据库了,直接写入 Excel 。
import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 获取列表页面数据<br /> :param maxNum: 最大抓取页数<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游记':<br /> # 如果是游记,则进入内页数据抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 获取内页数据<br /> :param url: 内页链接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 获取数据采集区<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 数据格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 数据写入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格写入数据成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
因为马蜂窝在游记的详情页面上有反爬的限制,小编这里为了简单,直接从浏览器中将 cookie copy 出来,加在了请求头上。
小编这里简单的爬取了 5 个列表页的信息,如下:
好像数据量并不是很多的样子,各位同学可以尝试爬取 50 页或者 100 页的数据,这样得到的结果会有比较不错的参考价值。
好了,本篇内容到这里就结束了,小编随后会将全部的文章索引整理出来推在公众号上,方便大家查阅。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
示例代码-Github:
示例代码-Gitee:
查看全部
小白学 Python 爬虫(42):春节去哪里玩(系列终篇)
人生苦短,我用 Python
前文传送门:
引言
首先恭喜看到这篇文章的同学,本篇内容为 「小白学 Python 爬虫」 系列的最后一篇。
看了下上面的前文传送门,加上这篇内容,总共有 42 篇,小编还是成就感满满,小编翻看了下公众号,第一篇文章是在 2019 年的 11 月 17 日推送的,大致数了数,将近两个月的时间。
当然,其中一些文章的质量并不高,很多都是在比较有限的时间中赶工赶出来的,还是感谢各位读者对小编的不离不弃,写的这么烂还没取关的绝对是真爱了。
正好下周就要过年了,从推送的时间算的话还有 10 个自然日左右的时间,可能很多同学可能过年是要出去玩的,那么去哪里玩就成了一个问题。
那么,怎么挑选去哪里玩最快的,小编想了想,直接去抓某站的数据吧,抓下来自己根据自己的情况查询下就好了。
那么今天的目标站是:马蜂窝。
这里小编还想说一点,虽然我们在前面 7、 8 篇文章中都是在讲如何使用爬虫框架 Scrapy ,说实话,小编并不觉得 Scrapy 有多方便,在一些简单的应用场景下,使用 Requests 库可能是最方便的选择, Scrapy 小编个人感觉还是更适合使用在一些中大型的爬虫项目中,简单的爬虫脚本使用最简单的技术栈就 ok 了,所以小编在本文中使用的技术栈还是 Requests + PyQuery 。
不要问为啥,问就是喜欢。
分析
首先我们访问链接,打开我们将要抓取的站点:。
这里是攻略的列表页,我们的目标是抓取来自游记的数据,其余的数据放过,原因是在游记中我们才能获取到一些具体的我们需要的数据。
数据的来源搞清楚了,接下来是翻页功能,只有清楚了如何翻页,我们才能源源不断的获取数据,否则就只能抓取第一页的数据了。
当把页面翻到最下面的时候就尴尬了,发现是自动加载更多,这个当然难不倒帅气逼人的小编我,掏出大杀器, Chrome 的开发者工具 F12 ,选到 network 标签页,再往下滚动一下,我们查看下这个页面发出的请求。
这个请求很有意思,请求的路径和我们访问的页面路径一样,但是请求类型变成 POST ,并且增加了请求参数,类型还是 Form 表单格式的。
截止这里,我们已经清楚了目标站点的数据路径以及翻页方式,虽然目前我们并不知道最大页数是多少,但是我们可以人为的设置一个最大页数,比如 100 或者 200 ,小编相信,这么大的站点上,几百页的游记应该是还有的。
代码
代码小编就直接贴出来,之前有同学希望数据是保存在 Excel 中的,本次实战的数据就不存数据库了,直接写入 Excel 。
import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 获取列表页面数据<br /> :param maxNum: 最大抓取页数<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游记':<br /> # 如果是游记,则进入内页数据抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 获取内页数据<br /> :param url: 内页链接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 获取数据采集区<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 数据格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 数据写入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格写入数据成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
因为马蜂窝在游记的详情页面上有反爬的限制,小编这里为了简单,直接从浏览器中将 cookie copy 出来,加在了请求头上。
小编这里简单的爬取了 5 个列表页的信息,如下:
好像数据量并不是很多的样子,各位同学可以尝试爬取 50 页或者 100 页的数据,这样得到的结果会有比较不错的参考价值。
好了,本篇内容到这里就结束了,小编随后会将全部的文章索引整理出来推在公众号上,方便大家查阅。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
示例代码-Github:
示例代码-Gitee:
一文搞懂爬虫Scrapy框架详解
网站优化 • 优采云 发表了文章 • 0 个评论 • 56 次浏览 • 2022-05-21 05:55
“Python爬虫Scrapy框架实践。”
大数据已经渗透到当今每一个行业和业务职能领域,成为重要的生产因素。”人们对于海量数据的挖掘和运用越来越密切,预示着爬虫工作者已经成为互联网数据公司的关键性职位,他们不但要精通数据抓取和分析,还要掌握搜索引擎和相关检索的算法,对内存、性能、分布式算法都要有一定的了解,并针对工作进程编排合理的布局。依据数据来预测某一种事物未来的发展趋势,以及对应的风险,提早解决未来即将遇到的风险,防范于未然。
一 Scrapy框架简介
Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
了解scrapy爬虫原理:Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构如下:
总结-scrapy大概流程如下:
Scrapy Engine:Scrapy引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。
Scheduler:调度器。从Scrapy Engine接受请求(requests)并排序列入队列,并在引擎再次请求时返回。用它来决定下一个抓取的网址是什么,同时去除重复的网址。
Downloader:下载器。抓取网页并将网页内容返还给Spiders。建立在twisted异步模型。
Spiders:爬虫。用户自定义的类,主要用来解析网页,提取Items,发送url跟进等新请求等。
Item Pipelines:管道。主要用来处理Spider解析出来的Items,进行按规则过滤,验证,持久化存储(如数据库存储)等
Downloader Middlewares:下载中间件。位于Scrapy Engine和Downloader之间,主要是处理Scrapy引擎与下载器之间的请求及响应。
Spider Middlewares:爬虫中间件。位于Scrapy Engine和Spiders之间,主要工作是处理Spiders的响应输入和请求输出。
Scheduler Middlewares:调度中间件。位于Scrapy Engine和Scheduler之间。主要工作是处理从Scrapy Engine发送到Scheduler的请求和响应。
二 Scrapy框架详解Scrapy由Python语言编写,是一个快速、高层次的屏幕抓取和Web抓取框架。1. 数据流向Scrapy数据流是由执行流程的核心引擎来控制的,流程如图所示。
框架组件数据流
1.ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
2.ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
3.ScrapyEngine向调度器请求下一个要爬取的url;
4.Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
5.页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
6.ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
7.Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
8.ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。
2Scrapy 的运作流程
制作 Scrapy 爬虫 一共需要 4 步:
1 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
2 明确目标 (编写 items.py):明确你想要抓取的目标,想要爬什么信息
3 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
4 存储内容 (pipelines.py):设计管道存储爬取内容
具体流程
1、scrapy安装
pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
检查是否安装成功:
scrapy versionScrapy 2.5.0
scrapy常用命令使用:
Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
2、创建项目
//创建一个测试项目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
3、第一个爬虫项目
注释:
scrapy genspider -l 查看当前可以使用的爬虫模板
scrapy genspider -t 创建爬虫文件
1.scrapy startproject scrapyproject2.在工程目录下创建爬虫baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默认)、crawl、csvfeed、xmlfeed这里name是爬虫的名字;domain是设置allowed_domains以及start_urls,这两个属性可以在爬虫类中修改<br /><br />cd scrapyprojectscrapy genspider baidu baidu.com (baidu 为爬虫的名称,baidu.com为要爬取的网站的域名)<br />输出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打开第一步创建的项目
目录及文件结构:
文件说明:
scrapy.cfg 项目的配置信息,主要为Scrapy命令行工具提供一个基础的配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py 设置数据存储模板,用于结构化数据,如:Django的Model
pipelines 数据处理行为,如:一般结构化的数据持久化
settings.py 配置文件,如:递归的层数、并发数,延迟下载等
spiders 爬虫目录,如:创建文件,编写爬虫规则
注意:一般创建爬虫文件时,以网站域名命名。
4. cd 项目目录,重写parse函数,然后启动爬虫,命令:
注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
scrapy crawl baidu
生成爬取结果
打开是界面:
05Scrapy校花网爬取实践
以校花网为例进行爬取,校花网:
创建xiaohuar spider:
scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
准备: 查看全部
一文搞懂爬虫Scrapy框架详解
“Python爬虫Scrapy框架实践。”
大数据已经渗透到当今每一个行业和业务职能领域,成为重要的生产因素。”人们对于海量数据的挖掘和运用越来越密切,预示着爬虫工作者已经成为互联网数据公司的关键性职位,他们不但要精通数据抓取和分析,还要掌握搜索引擎和相关检索的算法,对内存、性能、分布式算法都要有一定的了解,并针对工作进程编排合理的布局。依据数据来预测某一种事物未来的发展趋势,以及对应的风险,提早解决未来即将遇到的风险,防范于未然。
一 Scrapy框架简介
Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
了解scrapy爬虫原理:Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构如下:
总结-scrapy大概流程如下:
Scrapy Engine:Scrapy引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。
Scheduler:调度器。从Scrapy Engine接受请求(requests)并排序列入队列,并在引擎再次请求时返回。用它来决定下一个抓取的网址是什么,同时去除重复的网址。
Downloader:下载器。抓取网页并将网页内容返还给Spiders。建立在twisted异步模型。
Spiders:爬虫。用户自定义的类,主要用来解析网页,提取Items,发送url跟进等新请求等。
Item Pipelines:管道。主要用来处理Spider解析出来的Items,进行按规则过滤,验证,持久化存储(如数据库存储)等
Downloader Middlewares:下载中间件。位于Scrapy Engine和Downloader之间,主要是处理Scrapy引擎与下载器之间的请求及响应。
Spider Middlewares:爬虫中间件。位于Scrapy Engine和Spiders之间,主要工作是处理Spiders的响应输入和请求输出。
Scheduler Middlewares:调度中间件。位于Scrapy Engine和Scheduler之间。主要工作是处理从Scrapy Engine发送到Scheduler的请求和响应。
二 Scrapy框架详解Scrapy由Python语言编写,是一个快速、高层次的屏幕抓取和Web抓取框架。1. 数据流向Scrapy数据流是由执行流程的核心引擎来控制的,流程如图所示。
框架组件数据流
1.ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
2.ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
3.ScrapyEngine向调度器请求下一个要爬取的url;
4.Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
5.页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
6.ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
7.Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
8.ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。
2Scrapy 的运作流程
制作 Scrapy 爬虫 一共需要 4 步:
1 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
2 明确目标 (编写 items.py):明确你想要抓取的目标,想要爬什么信息
3 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
4 存储内容 (pipelines.py):设计管道存储爬取内容
具体流程
1、scrapy安装
pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
检查是否安装成功:
scrapy versionScrapy 2.5.0
scrapy常用命令使用:
Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
2、创建项目
//创建一个测试项目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
3、第一个爬虫项目
注释:
scrapy genspider -l 查看当前可以使用的爬虫模板
scrapy genspider -t 创建爬虫文件
1.scrapy startproject scrapyproject2.在工程目录下创建爬虫baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默认)、crawl、csvfeed、xmlfeed这里name是爬虫的名字;domain是设置allowed_domains以及start_urls,这两个属性可以在爬虫类中修改<br /><br />cd scrapyprojectscrapy genspider baidu baidu.com (baidu 为爬虫的名称,baidu.com为要爬取的网站的域名)<br />输出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打开第一步创建的项目
目录及文件结构:
文件说明:
scrapy.cfg 项目的配置信息,主要为Scrapy命令行工具提供一个基础的配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py 设置数据存储模板,用于结构化数据,如:Django的Model
pipelines 数据处理行为,如:一般结构化的数据持久化
settings.py 配置文件,如:递归的层数、并发数,延迟下载等
spiders 爬虫目录,如:创建文件,编写爬虫规则
注意:一般创建爬虫文件时,以网站域名命名。
4. cd 项目目录,重写parse函数,然后启动爬虫,命令:
注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
scrapy crawl baidu
生成爬取结果
打开是界面:
05Scrapy校花网爬取实践
以校花网为例进行爬取,校花网:
创建xiaohuar spider:
scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
准备:
Python爬虫—破解JS加密的Cookie
网站优化 • 优采云 发表了文章 • 0 个评论 • 285 次浏览 • 2022-05-21 02:21
專 欄
❈Jerry,Python中文社区专栏作者。
blog:
github:
❈前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。
通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。
发现问题
打开Fiddler软件,用浏览器打开目标站点() 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?
仔细观察两次返回的结果可以发现:
1、第二次请求比第一次请求的Cookie内容多了个这个_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
2、第一次返回的内容一些复杂看不懂的JS代码,第二次返回的就是正确的内容
其实这是网站反爬虫的常用手段。大致过程是这样的:首次请求数据时,服务端返回动态的混淆加密过的JS,而这段JS的作用是给Cookie添加新的内容用于服务端验证,此时返回的状态码是521。浏览器带上新的Cookie再次请求,服务端验证Cookie通过返回数据(这也是为嘛代码不能返回数据的原因)。
解决问题
其实我第一次遇到这样的问题是,一开始想的就是既然你是用JS生成的Cookie, 那么我也可以将JS函数翻译成Python运行。但是最后还是发现我太傻太天真,因为现在的JS都流行混淆加密,原始的JS这样的:
<p>function lq(VA) {
var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo] 查看全部
Python爬虫—破解JS加密的Cookie
專 欄
❈Jerry,Python中文社区专栏作者。
blog:
github:
❈前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。
通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。
发现问题
打开Fiddler软件,用浏览器打开目标站点() 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?
仔细观察两次返回的结果可以发现:
1、第二次请求比第一次请求的Cookie内容多了个这个_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
2、第一次返回的内容一些复杂看不懂的JS代码,第二次返回的就是正确的内容
其实这是网站反爬虫的常用手段。大致过程是这样的:首次请求数据时,服务端返回动态的混淆加密过的JS,而这段JS的作用是给Cookie添加新的内容用于服务端验证,此时返回的状态码是521。浏览器带上新的Cookie再次请求,服务端验证Cookie通过返回数据(这也是为嘛代码不能返回数据的原因)。
解决问题
其实我第一次遇到这样的问题是,一开始想的就是既然你是用JS生成的Cookie, 那么我也可以将JS函数翻译成Python运行。但是最后还是发现我太傻太天真,因为现在的JS都流行混淆加密,原始的JS这样的:
<p>function lq(VA) {
var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo]
一只知乎爬虫
网站优化 • 优采云 发表了文章 • 0 个评论 • 195 次浏览 • 2022-05-15 05:53
本文经作者授权发布。
文 | 程柳锋@Tencent
爬虫的基本流程
网络爬虫的基本工作流程如下:
爬虫的抓取策略
在爬虫系统中,待抓取 URL 队列是很重要的一部分。待抓取 URL 队列中的 URL 以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些 URL 排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:
了解了爬虫的工作流程和爬取策略后,就可以动手实现一个爬虫了!那么在 python 里怎么实现呢?
技术栈基本实现
下面是一个伪代码
<p>import Queue
initial_page = "https://www.zhihu.com/people/gaoming623"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直进行
if url_queue.size()>0:
current_url = url_queue.get() #拿出队例中第一个的 url
store(current_url) #把这个 url 代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个 url 里链向的 url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break</p>
如果你直接加工一下上面的代码直接运行的话,你需要很长的时间才能爬下整个知乎用户的信息,毕竟知乎有 6000 万月活跃用户。更别说 Google 这样的搜索引擎需要爬下全网的内容了。那么问题出现在哪里?
布隆过滤器
需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有 N 个网站,那么分析一下判重的复杂度就是 N*log(N),因为所有网页要遍历一次,而每次判重用 set 的话需要 log(N) 的复杂度。OK,我知道 python 的 set 实现是 hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种 hash 的方法,但是它的特点是,它可以使用固定的内存(不随 url 的数量而增长)以 O(1) 的效率判定 url 是否已经在 set 中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个 url 不在 set 中,BF 可以 100%确定这个 url 没有看过。但是如果这个 url 在 set 中,它会告诉你:这个 url 应该已经出现过,不过我有 2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。
<p># bloom_filter.py
BIT_SIZE = 5000000
class BloomFilter:
def __init__(self):
# Initialize bloom filter, set size and all bits to 0
bit_array = bitarray(BIT_SIZE)
bit_array.setall(0)
self.bit_array = bit_array
def add(self, url):
# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
# Here use 7 hash functions.
point_list = self.get_postions(url)
for b in point_list:
self.bit_array[b] = 1
def contains(self, url):
# Check if a url is in a collection
point_list = self.get_postions(url)
result = True
for b in point_list:
result = result and self.bit_array[b]
return result
def get_postions(self, url):
# Get points positions in bit vector.
point1 = mmh3.hash(url, 41) % BIT_SIZE
point2 = mmh3.hash(url, 42) % BIT_SIZE
point3 = mmh3.hash(url, 43) % BIT_SIZE
point4 = mmh3.hash(url, 44) % BIT_SIZE
point5 = mmh3.hash(url, 45) % BIT_SIZE
point6 = mmh3.hash(url, 46) % BIT_SIZE
point7 = mmh3.hash(url, 47) % BIT_SIZE
return [point1, point2, point3, point4, point5, point6, point7]</p>
BF 详细的原理参考我之前写的文章:布隆过滤器(Bloom Filter) 的原理和实现
建表
用户有价值的信息包括用户名、简介、行业、院校、专业及在平台上活动的数据比如回答数、文章数、提问数、粉丝数等等。
用户信息存储的表结构如下:
<p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
-- User base information table
CREATE TABLE `t_user` (
`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`brief_info` varchar(400) COMMENT '个人简介',
`industry` varchar(50) COMMENT '所处行业',
`education` varchar(50) COMMENT '毕业院校',
`major` varchar(50) COMMENT '主修专业',
`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答数',
`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章数',
`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提问数',
`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏数',
`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被关注数',
`followed_count` int(10) unsigned DEFAULT 0 COMMENT '关注数',
`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '关注直播数',
`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '关注话题数',
`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '关注专栏数',
`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '关注问题数',
`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '关注收藏夹数',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次编辑',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';</p>
网页下载后通过 XPath 进行解析,提取用户各个维度的数据,最后保存到数据库中。
反爬虫策略应对-Headers
一般网站会从几个维度来反爬虫:用户请求的 Headers,用户行为,网站和数据加载的方式。从用户请求的 Headers 反爬虫是最常见的策略,很多网站都会对 Headers 的 User-Agent 进行检测,还有一部分网站会对 Referer 进行检测(一些资源网站的防盗链就是检测 Referer)。
如果遇到了这类反爬虫机制,可以直接在爬虫中添加 Headers,将浏览器的 User-Agent 复制到爬虫的 Headers 中;或者将 Referer 值修改为目标网站域名。对于检测 Headers 的反爬虫,在爬虫中修改或者添加 Headers 就能很好的绕过。
<p>cookies = {
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
"n_c": "1",
"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
"Referer": "https://www.zhihu.com/"
}
r = requests.get(url, cookies = cookies, headers = headers)</p>
反爬虫策略应对-代理 IP 池
还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。
大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理 ip 后可以每请求几次更换一个 ip,这在 requests 或者 urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。目前知乎已经对爬虫做了限制,如果是单个 IP 的话,一段时间系统便会提示异常流量,无法继续爬取了。因此代理 IP 池非常关键。网上有个免费的代理 IP API:
<p>import requests
import random
class Proxy:
def __init__(self):
self.cache_ip_list = []
# Get random ip from free proxy api url.
def get_random_ip(self):
if not len(self.cache_ip_list):
api_url = 'http://api.xicidaili.com/free2016.txt'
try:
r = requests.get(api_url)
ip_list = r.text.split('rn')
self.cache_ip_list = ip_list
except Exception as e:
# Return null list when caught exception.
# In this case, crawler will not use proxy ip.
print e
return {}
proxy_ip = random.choice(self.cache_ip_list)
proxies = {'http': 'http://' proxy_ip}
return proxies</p>
后续
爬虫源代码:zhihu-crawler下载之后通过 pip 安装相关三方包后,运行$ python crawler.py 即可(喜欢的帮忙点个 star 哈,同时也方便看到后续功能的更新)
运行截图:
查看全部
一只知乎爬虫
本文经作者授权发布。
文 | 程柳锋@Tencent
爬虫的基本流程
网络爬虫的基本工作流程如下:
爬虫的抓取策略
在爬虫系统中,待抓取 URL 队列是很重要的一部分。待抓取 URL 队列中的 URL 以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些 URL 排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:
了解了爬虫的工作流程和爬取策略后,就可以动手实现一个爬虫了!那么在 python 里怎么实现呢?
技术栈基本实现
下面是一个伪代码
<p>import Queue
initial_page = "https://www.zhihu.com/people/gaoming623"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直进行
if url_queue.size()>0:
current_url = url_queue.get() #拿出队例中第一个的 url
store(current_url) #把这个 url 代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个 url 里链向的 url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break</p>
如果你直接加工一下上面的代码直接运行的话,你需要很长的时间才能爬下整个知乎用户的信息,毕竟知乎有 6000 万月活跃用户。更别说 Google 这样的搜索引擎需要爬下全网的内容了。那么问题出现在哪里?
布隆过滤器
需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有 N 个网站,那么分析一下判重的复杂度就是 N*log(N),因为所有网页要遍历一次,而每次判重用 set 的话需要 log(N) 的复杂度。OK,我知道 python 的 set 实现是 hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种 hash 的方法,但是它的特点是,它可以使用固定的内存(不随 url 的数量而增长)以 O(1) 的效率判定 url 是否已经在 set 中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个 url 不在 set 中,BF 可以 100%确定这个 url 没有看过。但是如果这个 url 在 set 中,它会告诉你:这个 url 应该已经出现过,不过我有 2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。
<p># bloom_filter.py
BIT_SIZE = 5000000
class BloomFilter:
def __init__(self):
# Initialize bloom filter, set size and all bits to 0
bit_array = bitarray(BIT_SIZE)
bit_array.setall(0)
self.bit_array = bit_array
def add(self, url):
# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
# Here use 7 hash functions.
point_list = self.get_postions(url)
for b in point_list:
self.bit_array[b] = 1
def contains(self, url):
# Check if a url is in a collection
point_list = self.get_postions(url)
result = True
for b in point_list:
result = result and self.bit_array[b]
return result
def get_postions(self, url):
# Get points positions in bit vector.
point1 = mmh3.hash(url, 41) % BIT_SIZE
point2 = mmh3.hash(url, 42) % BIT_SIZE
point3 = mmh3.hash(url, 43) % BIT_SIZE
point4 = mmh3.hash(url, 44) % BIT_SIZE
point5 = mmh3.hash(url, 45) % BIT_SIZE
point6 = mmh3.hash(url, 46) % BIT_SIZE
point7 = mmh3.hash(url, 47) % BIT_SIZE
return [point1, point2, point3, point4, point5, point6, point7]</p>
BF 详细的原理参考我之前写的文章:布隆过滤器(Bloom Filter) 的原理和实现
建表
用户有价值的信息包括用户名、简介、行业、院校、专业及在平台上活动的数据比如回答数、文章数、提问数、粉丝数等等。
用户信息存储的表结构如下:
<p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
-- User base information table
CREATE TABLE `t_user` (
`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`brief_info` varchar(400) COMMENT '个人简介',
`industry` varchar(50) COMMENT '所处行业',
`education` varchar(50) COMMENT '毕业院校',
`major` varchar(50) COMMENT '主修专业',
`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答数',
`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章数',
`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提问数',
`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏数',
`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被关注数',
`followed_count` int(10) unsigned DEFAULT 0 COMMENT '关注数',
`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '关注直播数',
`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '关注话题数',
`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '关注专栏数',
`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '关注问题数',
`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '关注收藏夹数',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次编辑',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';</p>
网页下载后通过 XPath 进行解析,提取用户各个维度的数据,最后保存到数据库中。
反爬虫策略应对-Headers
一般网站会从几个维度来反爬虫:用户请求的 Headers,用户行为,网站和数据加载的方式。从用户请求的 Headers 反爬虫是最常见的策略,很多网站都会对 Headers 的 User-Agent 进行检测,还有一部分网站会对 Referer 进行检测(一些资源网站的防盗链就是检测 Referer)。
如果遇到了这类反爬虫机制,可以直接在爬虫中添加 Headers,将浏览器的 User-Agent 复制到爬虫的 Headers 中;或者将 Referer 值修改为目标网站域名。对于检测 Headers 的反爬虫,在爬虫中修改或者添加 Headers 就能很好的绕过。
<p>cookies = {
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
"n_c": "1",
"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
"Referer": "https://www.zhihu.com/"
}
r = requests.get(url, cookies = cookies, headers = headers)</p>
反爬虫策略应对-代理 IP 池
还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。
大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理 ip 后可以每请求几次更换一个 ip,这在 requests 或者 urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。目前知乎已经对爬虫做了限制,如果是单个 IP 的话,一段时间系统便会提示异常流量,无法继续爬取了。因此代理 IP 池非常关键。网上有个免费的代理 IP API:
<p>import requests
import random
class Proxy:
def __init__(self):
self.cache_ip_list = []
# Get random ip from free proxy api url.
def get_random_ip(self):
if not len(self.cache_ip_list):
api_url = 'http://api.xicidaili.com/free2016.txt'
try:
r = requests.get(api_url)
ip_list = r.text.split('rn')
self.cache_ip_list = ip_list
except Exception as e:
# Return null list when caught exception.
# In this case, crawler will not use proxy ip.
print e
return {}
proxy_ip = random.choice(self.cache_ip_list)
proxies = {'http': 'http://' proxy_ip}
return proxies</p>
后续
爬虫源代码:zhihu-crawler下载之后通过 pip 安装相关三方包后,运行$ python crawler.py 即可(喜欢的帮忙点个 star 哈,同时也方便看到后续功能的更新)
运行截图:
c爬虫抓取网页数据正常情况下发生的场景是什么?
网站优化 • 优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2022-09-06 16:02
c爬虫抓取网页数据正常情况下发生的场景是:用户发起一次请求,从浏览器的user-agent(浏览器上面一个host或者cookie)里面获取对应的body,然后交给爬虫解析交给c段发起连接请求,两边继续一对一的发起请求,但是一般情况下连接建立得不是太多,所以一般来说单方面只能发起一次连接请求。但是,机器比较多的情况下,系统可能就要发起一次连接请求了,比如加入了多种进程,那么这个连接请求可能连接多个进程,甚至数十个进程,在本文中,我们以一个前端每秒发起三次连接请求为例,将爬虫和后端连接请求相连接原理一次连接请求解析图解1:从user-agent我们知道用户浏览器里面的user-agent,浏览器在接收到了连接请求之后,首先会首先去查看请求里面的参数,看这些参数指定的资源是不是自己想要的,一般的发送的时候都会带着对应的headers,比如cookie之类的。
那么连接请求用到了哪些参数?user-agent:你要发送的user-agent-agent-名:你想发送的user-agent-agent-数:你想发送的user-agent-agent-cookie:你发送的user-agent-agent-数值那么requestheaders就是我们最常用的两个参数,头部的部分跟request没什么区别,这里重点看一下服务端参数第一个参数是cookie,前面请求里面也提到了,这个cookie在别的连接请求里面可能会用到;其次还有一个cookiebanner,也就是获取cookie的通道,一般来说可以用httpcookie连接推送http请求推送完cookie之后,后面这些数据就不再重复发送了。
第二个是服务端可以获取到的参数还有:cookie的host和max-age设置你的端口及子域名之类的对第一个参数进行检查,如果是一个比较熟悉自己程序请求的人,他会知道使用自己家的服务器,或者是自己家的机器,或者是自己家机器的内部连接,实际上你还可以在后台找到一些端口。对第二个参数,我们一般也是根据自己的业务来选择对应的参数,如果要抓的数据量大,我们的连接请求数可能就会很多,或者对user-agent提供了头部的cookie可以直接在相应设置连接请求,如果需要抓多个不同资源,在不太熟悉的情况下,最好就抓取一个,进行连接请求,这样可以减轻连接请求的负担,而使得连接效率更高。
2:给请求加上代理如果要发送多个user-agent请求,那么一个个的发送这种连接请求会很慢的,那么可以加一个代理服务器进行发送,代理服务器可以是公网的,也可以是爬虫自己的机器,速度比在本地发送要快,而且,代理服务器里面数据也是你自己配置的,这样可以防止恶意爬虫连接请求到你的程序。那么。 查看全部
c爬虫抓取网页数据正常情况下发生的场景是什么?
c爬虫抓取网页数据正常情况下发生的场景是:用户发起一次请求,从浏览器的user-agent(浏览器上面一个host或者cookie)里面获取对应的body,然后交给爬虫解析交给c段发起连接请求,两边继续一对一的发起请求,但是一般情况下连接建立得不是太多,所以一般来说单方面只能发起一次连接请求。但是,机器比较多的情况下,系统可能就要发起一次连接请求了,比如加入了多种进程,那么这个连接请求可能连接多个进程,甚至数十个进程,在本文中,我们以一个前端每秒发起三次连接请求为例,将爬虫和后端连接请求相连接原理一次连接请求解析图解1:从user-agent我们知道用户浏览器里面的user-agent,浏览器在接收到了连接请求之后,首先会首先去查看请求里面的参数,看这些参数指定的资源是不是自己想要的,一般的发送的时候都会带着对应的headers,比如cookie之类的。

那么连接请求用到了哪些参数?user-agent:你要发送的user-agent-agent-名:你想发送的user-agent-agent-数:你想发送的user-agent-agent-cookie:你发送的user-agent-agent-数值那么requestheaders就是我们最常用的两个参数,头部的部分跟request没什么区别,这里重点看一下服务端参数第一个参数是cookie,前面请求里面也提到了,这个cookie在别的连接请求里面可能会用到;其次还有一个cookiebanner,也就是获取cookie的通道,一般来说可以用httpcookie连接推送http请求推送完cookie之后,后面这些数据就不再重复发送了。

第二个是服务端可以获取到的参数还有:cookie的host和max-age设置你的端口及子域名之类的对第一个参数进行检查,如果是一个比较熟悉自己程序请求的人,他会知道使用自己家的服务器,或者是自己家的机器,或者是自己家机器的内部连接,实际上你还可以在后台找到一些端口。对第二个参数,我们一般也是根据自己的业务来选择对应的参数,如果要抓的数据量大,我们的连接请求数可能就会很多,或者对user-agent提供了头部的cookie可以直接在相应设置连接请求,如果需要抓多个不同资源,在不太熟悉的情况下,最好就抓取一个,进行连接请求,这样可以减轻连接请求的负担,而使得连接效率更高。
2:给请求加上代理如果要发送多个user-agent请求,那么一个个的发送这种连接请求会很慢的,那么可以加一个代理服务器进行发送,代理服务器可以是公网的,也可以是爬虫自己的机器,速度比在本地发送要快,而且,代理服务器里面数据也是你自己配置的,这样可以防止恶意爬虫连接请求到你的程序。那么。
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长
网站优化 • 优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2022-08-28 03:09
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长,节省了很多计算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要实现不同url间的切换时候需要session,并且每个spider的不同url解析采用不同的spiderspider所以三者实现逻辑差异不大以下代码是在scrapy框架下实现的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目录和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome浏览器命令fromin(url)fromax(url)#定位浏览器输入url时候的错误drivermanager(x。 查看全部
c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长

c爬虫抓取网页数据,使用session使得爬虫程序间隔时间不需要很长,节省了很多计算量。url解析,用urllib3本身并不需要session,而采用scrapy框架scrapy框架要实现不同url间的切换时候需要session,并且每个spider的不同url解析采用不同的spiderspider所以三者实现逻辑差异不大以下代码是在scrapy框架下实现的,spider如下:pythonurllib3installscrapyimportscrapyimportseleniumimportrequestsimporttimedefgetpage(url):selenium.webdriver.chrome().executable['chromedriver.exe']2:#文件目录和文件名有要求,一般>2try:drivermanager(x)exceptexceptionase:print('{0}'.format(e))returnnoneurl=getpage('')drivermanager(x)#使用chrome浏览器命令fromin(url)fromax(url)#定位浏览器输入url时候的错误drivermanager(x。
网络爬虫入门之python
网站优化 • 优采云 发表了文章 • 0 个评论 • 77 次浏览 • 2022-08-09 02:18
网络爬虫定义:
(来自于百度百科):网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
为什么要学:
在数据爆发式增长时代,如果这些数据得以分析利用,可以帮助企业更好的做出决策。网络爬虫技术,也是大数据分析的第一个环节。
Robots协议(爬虫协议)
全称是网络爬虫排除标准,通过该协议告诉搜索引擎哪些页面可以抓取,哪些不能抓取。是国际互联网通行的道德规范,虽然没有写入法律,但每一个爬虫都应该遵守这项协议。
python
(来自于百度百科):Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。
2021年10月,语言流行指数的编译器Tiobe将Python加冕为最受欢迎的编程语言,20年来首次将其置于Java、C和JavaScript之上。
版本很多,本次使用python3
python爬虫流程
重要知识点:
获取网页:requests、urllib、selenium
解析网页:re正则表达式、BeautifulSoup、lxml
存储数据:存入txt、csv、存入mysql、redis、mongodb等
框架:scrapy
python 安装
使用Anaconda科学计算环境下载python
安装步骤 自行搜索百度,有很多,其实就是下一步下一步。使用pip安装第三方库或者使用Anaconda安装第三方库。
编辑器:Pycharm
如果你使用Python安装包下载的python,推荐使用pycharm编辑器。下载免费版即可,官网好像被墙了。
python之初尝试
python之爬虫初尝试 查看全部
网络爬虫入门之python
网络爬虫定义:
(来自于百度百科):网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
为什么要学:
在数据爆发式增长时代,如果这些数据得以分析利用,可以帮助企业更好的做出决策。网络爬虫技术,也是大数据分析的第一个环节。
Robots协议(爬虫协议)
全称是网络爬虫排除标准,通过该协议告诉搜索引擎哪些页面可以抓取,哪些不能抓取。是国际互联网通行的道德规范,虽然没有写入法律,但每一个爬虫都应该遵守这项协议。
python
(来自于百度百科):Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。
2021年10月,语言流行指数的编译器Tiobe将Python加冕为最受欢迎的编程语言,20年来首次将其置于Java、C和JavaScript之上。

版本很多,本次使用python3
python爬虫流程
重要知识点:
获取网页:requests、urllib、selenium
解析网页:re正则表达式、BeautifulSoup、lxml
存储数据:存入txt、csv、存入mysql、redis、mongodb等
框架:scrapy
python 安装
使用Anaconda科学计算环境下载python
安装步骤 自行搜索百度,有很多,其实就是下一步下一步。使用pip安装第三方库或者使用Anaconda安装第三方库。

编辑器:Pycharm
如果你使用Python安装包下载的python,推荐使用pycharm编辑器。下载免费版即可,官网好像被墙了。
python之初尝试
python之爬虫初尝试
c爬虫抓取网页数据,比如百度全部关键词爬虫。
网站优化 • 优采云 发表了文章 • 0 个评论 • 108 次浏览 • 2022-08-05 14:05
c爬虫抓取网页数据,比如百度全部关键词爬虫。update2:20190913又看了一下,问题中是纯元数据。本身元数据没有地域归属。这样设置,useragent提供的信息仅限于ip和mac地址,而你能爬取的并不是这些信息。你需要axios+request来注册scrapy,才能爬取以外的信息。以下为20190710补充:github上有提供examples:examples|scrapy学习。
nlp方面,有一些国内论坛可以去学习。比如,通过python的poc文本识别正则表达式(抓取百度网页上的文本信息,并翻译英文,但非微信的文章信息)。
如果你是零基础的话,推荐去csdn看看一个和你问题有相似需求的人在使用什么框架和数据库。web的话,爬虫爬取评论数据用前端selenium。找相关的网站翻译一下。如果可以看懂的话可以试着写一个爬虫这样。我目前是这么干的,具体不太懂。感觉时间比较紧,
回答你的问题首先要说明的是,市面上比较多,国内的,国外的,mongodb等等很多,我只知道其中的一款,如果你想学习爬虫的话,建议去学习一下,因为爬虫要对各种兼容性进行分析,可能你需要写几个框架,从最开始的caffe到其他的,从此要自己写框架,初学的话,这些框架你可以选择一个,其实安卓,ios都可以搭建自己的网站,反正不都是web吗,所以你也可以去学习一下。
并不是不会,是因为没经历过,作为初学者,建议还是先学一些框架,比如requests+xpath+beautifulsoup4(因为本人java基础不是很好,所以选择了前三个,做练习可以选择其他的)lxmlpyquery等等或者直接学一下flaskpyramid都可以。自己先去学一下其他的,然后了解一下api,通过各种api写一个网站,网站出来以后在选择一个框架,这样一来,一切都会水到渠成。 查看全部
c爬虫抓取网页数据,比如百度全部关键词爬虫。
c爬虫抓取网页数据,比如百度全部关键词爬虫。update2:20190913又看了一下,问题中是纯元数据。本身元数据没有地域归属。这样设置,useragent提供的信息仅限于ip和mac地址,而你能爬取的并不是这些信息。你需要axios+request来注册scrapy,才能爬取以外的信息。以下为20190710补充:github上有提供examples:examples|scrapy学习。

nlp方面,有一些国内论坛可以去学习。比如,通过python的poc文本识别正则表达式(抓取百度网页上的文本信息,并翻译英文,但非微信的文章信息)。
如果你是零基础的话,推荐去csdn看看一个和你问题有相似需求的人在使用什么框架和数据库。web的话,爬虫爬取评论数据用前端selenium。找相关的网站翻译一下。如果可以看懂的话可以试着写一个爬虫这样。我目前是这么干的,具体不太懂。感觉时间比较紧,

回答你的问题首先要说明的是,市面上比较多,国内的,国外的,mongodb等等很多,我只知道其中的一款,如果你想学习爬虫的话,建议去学习一下,因为爬虫要对各种兼容性进行分析,可能你需要写几个框架,从最开始的caffe到其他的,从此要自己写框架,初学的话,这些框架你可以选择一个,其实安卓,ios都可以搭建自己的网站,反正不都是web吗,所以你也可以去学习一下。
并不是不会,是因为没经历过,作为初学者,建议还是先学一些框架,比如requests+xpath+beautifulsoup4(因为本人java基础不是很好,所以选择了前三个,做练习可以选择其他的)lxmlpyquery等等或者直接学一下flaskpyramid都可以。自己先去学一下其他的,然后了解一下api,通过各种api写一个网站,网站出来以后在选择一个框架,这样一来,一切都会水到渠成。
c爬虫抓取网页数据更新的步骤是什么?怎么做
网站优化 • 优采云 发表了文章 • 0 个评论 • 291 次浏览 • 2022-06-29 07:02
c爬虫抓取网页数据更新的步骤:1.首先是获取目标网页的数据的方法,即获取这个网页所需要的数据。2.再是打包成数据包,下载到本地。然后对下载下来的数据做分析计算。有了本地的数据包,才能通过脚本更新网页。3.网页的更新即是用人工手动的方式取得网页最新的数据。这个过程需要使用抓包工具。4.http请求的代码以https格式写在代码最后。5.有人会问,这个代码在哪里?运行代码的时候,会用到浏览器开发者工具。
做爬虫的时候经常会用到一些爬虫工具,
可以使用多线程抓取,
我个人认为,
有个叫说手机app的那哥们,整天干这个。
曾经做过一段android全开源爬虫,可以爬lbs相关,更新比较及时,速度可以达到1000+,现在想想那是多年前的事了。
如果只爬公开数据(包括大数据),可以通过反爬虫机制。在androidapi409范围之内,比如:大商家之间的投票、大的赛事、大型论坛。在recaptcha加密机制之内,拿到中间地址。然后:翻墙找数据。(外国网站监控比较牛逼)在上一条的基础上,自己编写getheader或者cookie对爬虫,这个可以crawl,不过有点坑。
在自己程序中使用第三方爬虫,会和代理广告相关,自己肯定清楚相关的东西。或者agentdetector来监控哪个浏览器加速。有实力做爬虫网站比如一些专门做分析数据爬虫之类的东西,就是收费的东西,多爬一些数据吧。 查看全部
c爬虫抓取网页数据更新的步骤是什么?怎么做
c爬虫抓取网页数据更新的步骤:1.首先是获取目标网页的数据的方法,即获取这个网页所需要的数据。2.再是打包成数据包,下载到本地。然后对下载下来的数据做分析计算。有了本地的数据包,才能通过脚本更新网页。3.网页的更新即是用人工手动的方式取得网页最新的数据。这个过程需要使用抓包工具。4.http请求的代码以https格式写在代码最后。5.有人会问,这个代码在哪里?运行代码的时候,会用到浏览器开发者工具。
做爬虫的时候经常会用到一些爬虫工具,

可以使用多线程抓取,
我个人认为,
有个叫说手机app的那哥们,整天干这个。

曾经做过一段android全开源爬虫,可以爬lbs相关,更新比较及时,速度可以达到1000+,现在想想那是多年前的事了。
如果只爬公开数据(包括大数据),可以通过反爬虫机制。在androidapi409范围之内,比如:大商家之间的投票、大的赛事、大型论坛。在recaptcha加密机制之内,拿到中间地址。然后:翻墙找数据。(外国网站监控比较牛逼)在上一条的基础上,自己编写getheader或者cookie对爬虫,这个可以crawl,不过有点坑。
在自己程序中使用第三方爬虫,会和代理广告相关,自己肯定清楚相关的东西。或者agentdetector来监控哪个浏览器加速。有实力做爬虫网站比如一些专门做分析数据爬虫之类的东西,就是收费的东西,多爬一些数据吧。
数据分析|爬虫抓取东方财富网股吧帖子
网站优化 • 优采云 发表了文章 • 0 个评论 • 80 次浏览 • 2022-06-24 23:39
1前言
量化交易策略的研究主要涵盖了微观和宏观这两个方面,微观方面更多地是从市场价格和成交持仓这些基础信息为研究对象,通过算法计算出技术指标,再从技术指标的变化上构建交易模型。宏观方面则是基于更多的市场资讯开发交易模型,比如从CPI、PPI、货币发行量这些宏观经济指标为研究对象构建交易模型;或者是利用数据挖掘技术从新闻事件中挖掘出可能造成市场异常波动的事件,从而获得交易的时机。
我们知道知名股票论坛有点金投资家园、股天下、东方财富网股吧、和讯股吧、创幻论坛、MACD股市等等,笔者用的比较多的是东方财富网股吧。在课程《构建基于股票的量化交易系统》中我们以爬取东方财富网行业板块当日的行情数据为案例,介绍了网络爬虫的原理和方法,本节我们再介绍下如何爬取东方财富网股吧帖子的内容。
2
解析股吧帖子URL
首先通过浏览器访问伟星新材的股吧,查看该网页的URL为:
,002372.html,网页内容如下图所示:
当我们点击第2页、第3页后,查看下当前的URL分别为:
http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
因此得到了个股股吧URL的规律为:
, 002372_%d.html形式表示,
其中的规律比较直白,%d为论坛第几页,不过这个形式是按评论时间排列的网址,如果按发帖时间的排列网址是:
,002372,f_%d.html。
股吧的帖子由两部分组成,一部分为“财经评论”或“东方财富网”发布的公告或官方消息,另一部分为散户发布的讨论帖子,如下图所示:
前者的帖子URL为:
,cjpl,902659513.html,
后者的帖子URL为:
,002372,902629178.html
两者的URL都可在当前该股股吧HTML文件内容中搜寻到,如下所示:
因此“财经评论”、“东方财富网”或者散户发布的帖子,主要的特征为/news,在实现上我们可以先爬取到股吧HTML内容,然后通过正则表达式来筛选得到帖子的URL。
关于读取网页HTML内容的关键代码我们已经在课程《爬虫方式获取行业板块数据》一节中具体介绍过。需要注意的是Python2的urllib、urllib2和urlparse,已经在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的内容整合为urllib.request模块,urlparse整合为urllib.parse模块。
获取到HTML代码部分内容如下:
正则表达式筛选帖子URL,采用了pile和re.findall,实现代码如下:
其中正则表达式的\S+表示匹配多次非空白字符,然后使用findall函数找到匹配的所有字符串,并把它们作为一个列表返回。
然后是使用urljoin方法把整个url拼接好用于爬取单个帖子的标题内容,关键代码如下所示:
3创建爬虫URL队列
接下来我们把所有需要爬取的股吧页以及每页中的帖子的URL以队列的方式进行管理。Python中存储序列的类型有list、tuple、dict和set,它们之间的区别和特点简单的说:tuple不能修改其中的元素;set是无序集合,会自动去除重复元素;list是有序的集合;dict是一组key和value的组合。此次我们选择list作为队列的存储类型。
创建target_url_manager类,该类包含以下几个方法:
创建队列形式如下所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
4
解析股吧帖子内容
单个帖子爬取的内容包括三部分,帖子发表时间、作者及帖子标题,如下所示:
我们可以通过正则表达式进行提取,其中在组合正则表达式时,需要考虑到HTML代码中是否有重复的匹配关键字。作者和帖子标题正则代码如下,mainbody、zwcontentmain这些关键字在文本中仅出现一次,匹配程度较高。由于网站HTML代码的改动,表达式需要经常调整。
关键代码如下所示:
com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
发布时间正则代码如下,分两步逐渐明晰的去提取时间,由于search是扫描字符串找到这个RE 匹配的位置,因此增加group()返回匹配字符串。
pub_elems = re.search('.*?',html_cont2).group()#发表于 2020-02-11 09:54:48 东方财富Android版<br />pub_time = re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
<br />
另外,论坛帖子与当前的股价走势有时间联系,太早的帖子对现在无参考作用,因此需要删选近期的帖子。我们可以对时间进行判断,只有一个月之内发布的帖子才进行爬取并存储。获取今天的日期使用datetime.now().date(),然后与爬取的帖子时间日期比较,timedelta可在日期上做天days时间计算,但需要将时间转换为时间形式。
实现部分关键代码如下所示:
完成了单个帖子的内容爬取之后,我们采用迭代方法把全部帖子爬取一遍。我们通过两层迭代方法,第一层为页数,第二层为一页的股吧帖子数,将每个帖子的URL存储在列表中,通过迭代的方式一个个爬取帖子的内容。<br />
实现部分关键代码如下:
当我们爬取时发现某个帖子不存在,出现爬取信息异常时,可使用try...except...进行异常处理。
最终爬取到的帖子内容如下图所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
5
帖子内容存储为txt
我们可以将爬取信息写到txt文件中,打开方式的代码实现如下所示,a+为在文本尾部追加写入,而不是覆盖写入,codecs.open这个方法可以指定编码打开文件,而使用Python内置的open打开文件只能写入str类型。
f=codecs.open(name,'a+','utf-8')
此处我们创建一个output_txt类,该类中我们会分别实现打开文件、写文件和关闭文件这几个方法。代码如下所示:
接下来就可以一边爬取帖子内容,一边把内容写入到txt文件中。实现关键代码如下所示:
写入txt文件的效果如下所示:
我们也可以把爬取信息写到GUI工具中,我们知道在wxPython中文本框为wx.TextCtrl类,该类可以显示和编辑文本,这样一来就可以把帖子信息写到GUI工具中。显示效果如下所示:
6
总结
本小节我们通过爬虫方式得到股吧帖子中的各种内容,那么这些内容对于我们来说有什么意义吗?我们发现总有些人一直在唱空,制造恐慌的情绪,不过我们可以通过分类分析下这些空头评论和股价的涨跌有没有什么关联,是不是有写ID是专门来唱空的呢?感兴趣的朋友们可以试试!比如用词云这种方式,如下所示:
查看全部
数据分析|爬虫抓取东方财富网股吧帖子
1前言
量化交易策略的研究主要涵盖了微观和宏观这两个方面,微观方面更多地是从市场价格和成交持仓这些基础信息为研究对象,通过算法计算出技术指标,再从技术指标的变化上构建交易模型。宏观方面则是基于更多的市场资讯开发交易模型,比如从CPI、PPI、货币发行量这些宏观经济指标为研究对象构建交易模型;或者是利用数据挖掘技术从新闻事件中挖掘出可能造成市场异常波动的事件,从而获得交易的时机。
我们知道知名股票论坛有点金投资家园、股天下、东方财富网股吧、和讯股吧、创幻论坛、MACD股市等等,笔者用的比较多的是东方财富网股吧。在课程《构建基于股票的量化交易系统》中我们以爬取东方财富网行业板块当日的行情数据为案例,介绍了网络爬虫的原理和方法,本节我们再介绍下如何爬取东方财富网股吧帖子的内容。
2
解析股吧帖子URL
首先通过浏览器访问伟星新材的股吧,查看该网页的URL为:
,002372.html,网页内容如下图所示:
当我们点击第2页、第3页后,查看下当前的URL分别为:
http://guba.eastmoney.com/list,002372_2.htmlhttp://guba.eastmoney.com/list,002372_3.html
因此得到了个股股吧URL的规律为:
, 002372_%d.html形式表示,
其中的规律比较直白,%d为论坛第几页,不过这个形式是按评论时间排列的网址,如果按发帖时间的排列网址是:
,002372,f_%d.html。
股吧的帖子由两部分组成,一部分为“财经评论”或“东方财富网”发布的公告或官方消息,另一部分为散户发布的讨论帖子,如下图所示:
前者的帖子URL为:
,cjpl,902659513.html,
后者的帖子URL为:
,002372,902629178.html
两者的URL都可在当前该股股吧HTML文件内容中搜寻到,如下所示:
因此“财经评论”、“东方财富网”或者散户发布的帖子,主要的特征为/news,在实现上我们可以先爬取到股吧HTML内容,然后通过正则表达式来筛选得到帖子的URL。
关于读取网页HTML内容的关键代码我们已经在课程《爬虫方式获取行业板块数据》一节中具体介绍过。需要注意的是Python2的urllib、urllib2和urlparse,已经在Python3中全部被整合到了urllib中,其中Python2的urllib和urllib2中的内容整合为urllib.request模块,urlparse整合为urllib.parse模块。
获取到HTML代码部分内容如下:
正则表达式筛选帖子URL,采用了pile和re.findall,实现代码如下:
其中正则表达式的\S+表示匹配多次非空白字符,然后使用findall函数找到匹配的所有字符串,并把它们作为一个列表返回。
然后是使用urljoin方法把整个url拼接好用于爬取单个帖子的标题内容,关键代码如下所示:
3创建爬虫URL队列
接下来我们把所有需要爬取的股吧页以及每页中的帖子的URL以队列的方式进行管理。Python中存储序列的类型有list、tuple、dict和set,它们之间的区别和特点简单的说:tuple不能修改其中的元素;set是无序集合,会自动去除重复元素;list是有序的集合;dict是一组key和value的组合。此次我们选择list作为队列的存储类型。
创建target_url_manager类,该类包含以下几个方法:
创建队列形式如下所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
4
解析股吧帖子内容
单个帖子爬取的内容包括三部分,帖子发表时间、作者及帖子标题,如下所示:
我们可以通过正则表达式进行提取,其中在组合正则表达式时,需要考虑到HTML代码中是否有重复的匹配关键字。作者和帖子标题正则代码如下,mainbody、zwcontentmain这些关键字在文本中仅出现一次,匹配程度较高。由于网站HTML代码的改动,表达式需要经常调整。
关键代码如下所示:
com_cont = re.compile(r'.*?zwconttbn.*?(.*?).*?social clearfix',re.DOTALL)
发布时间正则代码如下,分两步逐渐明晰的去提取时间,由于search是扫描字符串找到这个RE 匹配的位置,因此增加group()返回匹配字符串。
pub_elems = re.search('.*?',html_cont2).group()#发表于 2020-02-11 09:54:48 东方财富Android版<br />pub_time = re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()#2020-02-06
<br />
另外,论坛帖子与当前的股价走势有时间联系,太早的帖子对现在无参考作用,因此需要删选近期的帖子。我们可以对时间进行判断,只有一个月之内发布的帖子才进行爬取并存储。获取今天的日期使用datetime.now().date(),然后与爬取的帖子时间日期比较,timedelta可在日期上做天days时间计算,但需要将时间转换为时间形式。
实现部分关键代码如下所示:
完成了单个帖子的内容爬取之后,我们采用迭代方法把全部帖子爬取一遍。我们通过两层迭代方法,第一层为页数,第二层为一页的股吧帖子数,将每个帖子的URL存储在列表中,通过迭代的方式一个个爬取帖子的内容。<br />
实现部分关键代码如下:
当我们爬取时发现某个帖子不存在,出现爬取信息异常时,可使用try...except...进行异常处理。
最终爬取到的帖子内容如下图所示:
完整代码可见课程《加推篇!爬虫抓取东方财富网股吧帖子》。
5
帖子内容存储为txt
我们可以将爬取信息写到txt文件中,打开方式的代码实现如下所示,a+为在文本尾部追加写入,而不是覆盖写入,codecs.open这个方法可以指定编码打开文件,而使用Python内置的open打开文件只能写入str类型。
f=codecs.open(name,'a+','utf-8')
此处我们创建一个output_txt类,该类中我们会分别实现打开文件、写文件和关闭文件这几个方法。代码如下所示:
接下来就可以一边爬取帖子内容,一边把内容写入到txt文件中。实现关键代码如下所示:
写入txt文件的效果如下所示:
我们也可以把爬取信息写到GUI工具中,我们知道在wxPython中文本框为wx.TextCtrl类,该类可以显示和编辑文本,这样一来就可以把帖子信息写到GUI工具中。显示效果如下所示:
6
总结
本小节我们通过爬虫方式得到股吧帖子中的各种内容,那么这些内容对于我们来说有什么意义吗?我们发现总有些人一直在唱空,制造恐慌的情绪,不过我们可以通过分类分析下这些空头评论和股价的涨跌有没有什么关联,是不是有写ID是专门来唱空的呢?感兴趣的朋友们可以试试!比如用词云这种方式,如下所示:
数据抓取学习3|web scraper爬虫使用方法—进阶篇
网站优化 • 优采云 发表了文章 • 0 个评论 • 779 次浏览 • 2022-06-20 04:44
上一篇文章讲了web scraper的基础操作,今天跟大家分享web scraper爬虫的一些进阶使用方法,学会了它,大概80%的网站元素都可以抓取了。
它的步骤都是:
创建一个站点Create sitemap—新增选择器Add new selector—点击Scrape抓取,不同的是选择器中Type的选择。
在进阶篇中,主要讲的就是这几个Type的使用。
目录
页内提取多个字段Type=Element
选择树Selector graph
选择快捷键Enable key
不规则分页Type=Element scroll down/Element click
二三级页面元素采集Type=Type=Link
抓取表单Type=Table
Delay的设置
1.页内提取多个字段(Type=Element)
如上图,如果想要同时抓取这个回答中的标题、点赞人数、回答的正文,就要用到Element这个选择器,它表示的是元素集,各个元素组成的一个元素集。比如上图中的回答中的标题、点赞人数、回答的正文、评论数就在一个元素集里。
具体的操作步骤如下:
新建一个站点地图Create sitemap—新建选择器Add new selector—新建子选择器—抓取
点击Select选取元素,这个是元素集,所以选择时要把整个元素集都框选中。具体步骤如下图,在基础篇中讲过,在选择时如果是type(1),说明这个页面的元素没有选完,这里再选择下一个元素集就可以了。
在新建选择器时选择Element这个选择器,勾选Multiple。
建好之后,点击这个选择器,进入到选择子器页面,然后再新建子选择器,选择需要抓取的页面元素。比如:标题、正文、点赞数、评论数。
子元素:标题、正文、点赞数、评论数这些都是文本,Type选择Text就可以了。
2.选择树Selector graph
在Sitemap的下拉菜单中有一个Selector graph的选择,通过它可以查看选择器之间的逻辑关系。
这个例子中元素集与元素之间的关系。
3.选择快捷键(Enable key)
用鼠标选择页面元素,有时候会出现选择错误或者是一点击就跳到的另外一个页面,这时候可以利用Enable key这个快捷操作去选取元素。
勾选Enable key ,把鼠标悬停在你要选择的元素上,待采集字段变绿后点击键盘S键选择。
4.不规则分页Type=Element scroll down/Element click
像下图中这种,需要鼠标向下滚动和点击“加载更多”,网页才会加载出新的内容。
这类网站的元素,可以分别利用选择器Type中的Element scroll down和Element click来进行抓取。
下面这个实例:收集IT桔子中金融类公司的公司名,公司简介。
这里需要鼠标点击“加载更多”才会出现新的内容。
新建一个站点地图后,新增选择器,在Type中选择Element click,点击Selector中的Select,选择元素集。
在Click selector点击Select,选择“加载更多”。
Click type 中选择Click more,因为这条类目内容很多,需要点击多次的“加载更多”,如果需要点击一次的话,选择Click once就可以。
Click element uniquenss选择unique CSS Selector。
勾选Multiple,注意在子选择器中就不用勾选。
这里加载可能会出现一点延时,所以可以加一个1000ms的延时。
然后再分别建立公司标题和公司简介的子选择器,进行抓取即可。
5.二三级页面元素采集Type=Link
还是知乎的例子,如果还想要收集这个问题的关注人数和浏览量,但这两个数据在另外一个页面,这里就需要用到选择器中Type=Link的选项,它表示的是指向这个文本背后的链接。
具体的操作步骤如下:
在元素集的子选择器中新建一个link的子选择器。
Type选择Link,选中标题,这里会看到出现标题的链接。
在link的下面再新建两个选择器,分别抓取关注和浏览量的数据。
看下这个抓取的逻辑树,理解就更清晰了:
6.抓取表单Type=Table
利用Type=Table
以抓取优采云票余票信息为例子。
网址链接:
在选择器中选择Type=Table,Selector选择整个表格。
Header row selector,选择表头,这例子中选择数据第一行为表头,再修改表头的名字,如果选择第一行为表头的话,只能抓取出发地、目的地、余票数量三个元素,详细的每日余票量抓取不了。
修改表头的标注
Data rows selector中选择所以抓取的数据项。
7.Delay的设置
在操作过程中,但选择器多了之后,大家会看到很多Delay的设置,下面说说需要设置Delay的情况。
点击Scrape后,这里的Delay,它针对的是全局,所有链接发生变化的情况。
点击分页、加载更多、滚动下拉这类页面需要时间加载是,就设置delay,推荐2000ms。
元素集中的子选择器可以不设置delay。
小结
讲解了web scraper的进阶操作后,是不是发现又有很多网站数据可以抓取了。
进阶篇中主要的知识点有:
1.根据抓取元素的不同情况,选择不同的Type
2.选择树Selector graph
选择器之间的逻辑关系。
3.选择快捷键Enable key
4.Delay的设置
页面需要时间加载的情况设置Delay,元素集中的子选择器可以不设 置。
5.子选择器中的Multiple不用勾选
6.常见的问题
操作过程中会需要两个常见问题:
思考题
在知乎例子的这个抓取结果中,回答正文中,没有把回答的全文抓取完。在网站上“阅读全文”这四个字需要用鼠标点开,爬虫才能把全部回答抓取完,怎么设置这个选择器呢?
大家可以先思考,尝试自己操作一下。
公众号回复“答案”,就可获取具体的操作步骤。
注:我学习课程为三节课的《人人都能学会的数据爬虫课》,此次仅为纯粹的学习分享。
搬运工的苦劳
苹果专用赞赏二维码 查看全部
数据抓取学习3|web scraper爬虫使用方法—进阶篇
上一篇文章讲了web scraper的基础操作,今天跟大家分享web scraper爬虫的一些进阶使用方法,学会了它,大概80%的网站元素都可以抓取了。
它的步骤都是:
创建一个站点Create sitemap—新增选择器Add new selector—点击Scrape抓取,不同的是选择器中Type的选择。
在进阶篇中,主要讲的就是这几个Type的使用。
目录
页内提取多个字段Type=Element
选择树Selector graph
选择快捷键Enable key
不规则分页Type=Element scroll down/Element click
二三级页面元素采集Type=Type=Link
抓取表单Type=Table
Delay的设置
1.页内提取多个字段(Type=Element)
如上图,如果想要同时抓取这个回答中的标题、点赞人数、回答的正文,就要用到Element这个选择器,它表示的是元素集,各个元素组成的一个元素集。比如上图中的回答中的标题、点赞人数、回答的正文、评论数就在一个元素集里。
具体的操作步骤如下:
新建一个站点地图Create sitemap—新建选择器Add new selector—新建子选择器—抓取
点击Select选取元素,这个是元素集,所以选择时要把整个元素集都框选中。具体步骤如下图,在基础篇中讲过,在选择时如果是type(1),说明这个页面的元素没有选完,这里再选择下一个元素集就可以了。
在新建选择器时选择Element这个选择器,勾选Multiple。
建好之后,点击这个选择器,进入到选择子器页面,然后再新建子选择器,选择需要抓取的页面元素。比如:标题、正文、点赞数、评论数。
子元素:标题、正文、点赞数、评论数这些都是文本,Type选择Text就可以了。
2.选择树Selector graph
在Sitemap的下拉菜单中有一个Selector graph的选择,通过它可以查看选择器之间的逻辑关系。
这个例子中元素集与元素之间的关系。
3.选择快捷键(Enable key)
用鼠标选择页面元素,有时候会出现选择错误或者是一点击就跳到的另外一个页面,这时候可以利用Enable key这个快捷操作去选取元素。
勾选Enable key ,把鼠标悬停在你要选择的元素上,待采集字段变绿后点击键盘S键选择。
4.不规则分页Type=Element scroll down/Element click
像下图中这种,需要鼠标向下滚动和点击“加载更多”,网页才会加载出新的内容。
这类网站的元素,可以分别利用选择器Type中的Element scroll down和Element click来进行抓取。
下面这个实例:收集IT桔子中金融类公司的公司名,公司简介。
这里需要鼠标点击“加载更多”才会出现新的内容。
新建一个站点地图后,新增选择器,在Type中选择Element click,点击Selector中的Select,选择元素集。
在Click selector点击Select,选择“加载更多”。
Click type 中选择Click more,因为这条类目内容很多,需要点击多次的“加载更多”,如果需要点击一次的话,选择Click once就可以。
Click element uniquenss选择unique CSS Selector。
勾选Multiple,注意在子选择器中就不用勾选。
这里加载可能会出现一点延时,所以可以加一个1000ms的延时。
然后再分别建立公司标题和公司简介的子选择器,进行抓取即可。
5.二三级页面元素采集Type=Link
还是知乎的例子,如果还想要收集这个问题的关注人数和浏览量,但这两个数据在另外一个页面,这里就需要用到选择器中Type=Link的选项,它表示的是指向这个文本背后的链接。
具体的操作步骤如下:
在元素集的子选择器中新建一个link的子选择器。
Type选择Link,选中标题,这里会看到出现标题的链接。
在link的下面再新建两个选择器,分别抓取关注和浏览量的数据。
看下这个抓取的逻辑树,理解就更清晰了:
6.抓取表单Type=Table
利用Type=Table
以抓取优采云票余票信息为例子。
网址链接:
在选择器中选择Type=Table,Selector选择整个表格。
Header row selector,选择表头,这例子中选择数据第一行为表头,再修改表头的名字,如果选择第一行为表头的话,只能抓取出发地、目的地、余票数量三个元素,详细的每日余票量抓取不了。
修改表头的标注
Data rows selector中选择所以抓取的数据项。
7.Delay的设置
在操作过程中,但选择器多了之后,大家会看到很多Delay的设置,下面说说需要设置Delay的情况。
点击Scrape后,这里的Delay,它针对的是全局,所有链接发生变化的情况。
点击分页、加载更多、滚动下拉这类页面需要时间加载是,就设置delay,推荐2000ms。
元素集中的子选择器可以不设置delay。
小结
讲解了web scraper的进阶操作后,是不是发现又有很多网站数据可以抓取了。
进阶篇中主要的知识点有:
1.根据抓取元素的不同情况,选择不同的Type
2.选择树Selector graph
选择器之间的逻辑关系。
3.选择快捷键Enable key
4.Delay的设置
页面需要时间加载的情况设置Delay,元素集中的子选择器可以不设 置。
5.子选择器中的Multiple不用勾选
6.常见的问题
操作过程中会需要两个常见问题:
思考题
在知乎例子的这个抓取结果中,回答正文中,没有把回答的全文抓取完。在网站上“阅读全文”这四个字需要用鼠标点开,爬虫才能把全部回答抓取完,怎么设置这个选择器呢?
大家可以先思考,尝试自己操作一下。
公众号回复“答案”,就可获取具体的操作步骤。
注:我学习课程为三节课的《人人都能学会的数据爬虫课》,此次仅为纯粹的学习分享。
搬运工的苦劳
苹果专用赞赏二维码
Python爬虫之三:抓取猫眼电影TOP100
网站优化 • 优采云 发表了文章 • 0 个评论 • 107 次浏览 • 2022-06-18 02:42
今天我要利用requests库和正则表达式抓取猫眼电影Top100榜单。
运行平台:Windows
Python版本:Python3.6
IDE:Sublime Text
其他工具:Chrome浏览器
1. 抓取单页内容
浏览器打开猫眼电影首页,点击“榜单”,然后再点击"TOP100榜",就能看到想要的了。
接下来通过代码来获取网页的HTML代码。
运行结果如下:
2. 正则表达式提取有用信息
在上图中,已经标注出我们将要提取的内容,下面用代码实现:
运行结果如下:
3. 保存信息
获取电影信息之后,要保存起来留用。要保存的有文本信息和电影封面。
下面为保存结果:
4.下载TOP100所有电影信息
通过点击标签页发现只是URL变化了:
修改main函数以动态改变URL:
到此我们已经将TOP100的电影信息和封面全部得到了。
5.多线程抓取
此次抓取的数据不算多,但是为了学习,使用多进程进行抓取,以应对以后大量的数据抓取。
下面为普通抓取和多进程抓取的时间对比:
以下为完整代码: 查看全部
Python爬虫之三:抓取猫眼电影TOP100
今天我要利用requests库和正则表达式抓取猫眼电影Top100榜单。
运行平台:Windows
Python版本:Python3.6
IDE:Sublime Text
其他工具:Chrome浏览器
1. 抓取单页内容
浏览器打开猫眼电影首页,点击“榜单”,然后再点击"TOP100榜",就能看到想要的了。
接下来通过代码来获取网页的HTML代码。
运行结果如下:
2. 正则表达式提取有用信息
在上图中,已经标注出我们将要提取的内容,下面用代码实现:
运行结果如下:
3. 保存信息
获取电影信息之后,要保存起来留用。要保存的有文本信息和电影封面。
下面为保存结果:
4.下载TOP100所有电影信息
通过点击标签页发现只是URL变化了:
修改main函数以动态改变URL:
到此我们已经将TOP100的电影信息和封面全部得到了。
5.多线程抓取
此次抓取的数据不算多,但是为了学习,使用多进程进行抓取,以应对以后大量的数据抓取。
下面为普通抓取和多进程抓取的时间对比:
以下为完整代码:
高性能异步并发爬虫!- colly 自动抓取资讯
网站优化 • 优采云 发表了文章 • 0 个评论 • 219 次浏览 • 2022-06-12 08:31
colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬虫界的大佬。本文用其抓取博文资讯,从收集器实例配置,goQuery 进行 dom 节点数据抓取,自动分页访问,到 csv 数据持久化,json 控制台输出,全程简单直观。
Code
抓取数据入口为社区某用户博客列表页,比如
package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog数据<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 数据持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.准备收集器实例<br /> c := colly.NewCollector(<br /> // 开启本机debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止页面重复下载<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析页面数据<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子项<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正则匹配替换,字符串转整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一页<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 启动<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 输出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 显示收集器的打印信息<br /> log.Println(c)<br />}<br />
Output
控制台输出
....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 与 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 进阶笔记",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在线聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
csv 文本输出
ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取动态网页,https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名类 与 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大话并发,https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元运算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,笔试之 模板变量替换,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,笔试之 连续数增维,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,笔试之 一行代码求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
Colly 查看全部
高性能异步并发爬虫!- colly 自动抓取资讯
colly 在 golang 中的地位,比之 scrapy 在 python 的作用,都是爬虫界的大佬。本文用其抓取博文资讯,从收集器实例配置,goQuery 进行 dom 节点数据抓取,自动分页访问,到 csv 数据持久化,json 控制台输出,全程简单直观。
Code
抓取数据入口为社区某用户博客列表页,比如
package main<br /><br />import (<br /> "encoding/csv"<br /> "encoding/json"<br /> "log"<br /> "os"<br /> "regexp"<br /> "strconv"<br /> "strings"<br /><br /> "github.com/gocolly/colly"<br />)<br /><br />// Article 抓取blog数据<br />type Article struct {<br /> ID int `json:"id,omitempty"`<br /> Title string `json:"title,omitempty"`<br /> URL string `json:"url,omitempty"`<br /> Created string `json:"created,omitempty"`<br /> Reads string `json:"reads,omitempty"`<br /> Comments string `json:"comments,omitempty"`<br /> Feeds string `json:"feeds,omitempty"`<br />}<br /><br />// 数据持久化<br />func csvSave(fName string, data []Article) error {<br /> file, err := os.Create(fName)<br /> if err != nil {<br /> log.Fatalf("Cannot create file %q: %s\n", fName, err)<br /> }<br /> defer file.Close()<br /> writer := csv.NewWriter(file)<br /> defer writer.Flush()<br /><br /> writer.Write([]string{"ID", "Title", "URL", "Created", "Reads", "Comments", "Feeds"})<br /> for _, v := range data {<br /> writer.Write([]string{strconv.Itoa(v.ID), v.Title, v.URL, v.Created, v.Reads, v.Comments, v.Feeds})<br /> }<br /> return nil<br />}<br /><br />func main() {<br /> articles := make([]Article, 0, 200)<br /> // 1.准备收集器实例<br /> c := colly.NewCollector(<br /> // 开启本机debug<br /> // colly.Debugger(&debug.LogDebugger{}),<br /> colly.AllowedDomains("learnku.com"),<br /> // 防止页面重复下载<br /> // colly.CacheDir("./learnku_cache"),<br /> )<br /><br /> // 2.分析页面数据<br /> c.OnHTML("div.blog-article-list > .event", func(e *colly.HTMLElement) {<br /> article := Article{<br /> Title: e.ChildText("div.content > div.summary"),<br /> URL: e.ChildAttr("div.content a.title", "href"),<br /> Feeds: e.ChildText("div.item-meta > a:first-child"),<br /> }<br /> // 查找同一集合不同子项<br /> e.ForEach("div.content > div.meta > div.date>a", func(i int, el *colly.HTMLElement) {<br /> switch i {<br /> case 1:<br /> article.Created = el.Attr("data-tooltip")<br /> case 2:<br /> // 用空白切割字符串<br /> article.Reads = strings.Fields(el.Text)[1]<br /> case 3:<br /> article.Comments = strings.Fields(el.Text)[1]<br /> }<br /> })<br /> // 正则匹配替换,字符串转整型<br /> article.ID, _ = strconv.Atoi(regexp.MustCompile(`\d+`).FindAllString(article.URL, -1)[0])<br /> articles = append(articles, article)<br /> })<br /><br /> // 下一页<br /> c.OnHTML("a[href].page-link", func(e *colly.HTMLElement) {<br /> e.Request.Visit(e.Attr("href"))<br /> })<br /><br /> // 启动<br /> c.Visit("https://learnku.com/blog/pardon")<br /><br /> // 输出<br /> csvSave("pardon.csv", articles)<br /> enc := json.NewEncoder(os.Stdout)<br /> enc.SetIndent("", " ")<br /> enc.Encode(articles)<br /><br /> // 显示收集器的打印信息<br /> log.Println(c)<br />}<br />
Output
控制台输出
....<br /> "id": 30604,<br /> "title": "教程: TodoMVC 与 director 路由",<br /> "url": "https://learnku.com/articles/30604",<br /> "created": "2019-07-01 12:42:01",<br /> "reads": "650",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30579,<br /> "title": "flaskr 进阶笔记",<br /> "url": "https://learnku.com/articles/30579",<br /> "created": "2019-06-30 19:01:04",<br /> "reads": "895",<br /> "comments": "0",<br /> "feeds": "0"<br /> },<br /> {<br /> "id": 30542,<br /> "title": "教程 Redis+ flask+vue 在线聊天",<br /> "url": "https://learnku.com/articles/30542",<br /> "created": "2019-06-29 12:19:45",<br /> "reads": "2760",<br /> "comments": "1",<br /> "feeds": "2"<br /> }<br />]<br />2019/12/20 15:50:14 Requests made: 5 (5 responses) | Callbacks: OnRequest: 0, OnHTML: 2, OnResponse: 0, OnError: 0
csv 文本输出
ID,Title,URL,Created,Reads,Comments,Feeds<br />37991,ferret 爬取动态网页,https://learnku.com/articles/37991,2019-12-15 10:43:03,219,0,3<br />37803,匿名类 与 索引重建,https://learnku.com/articles/37803,2019-12-09 19:35:09,323,1,0<br />37476,大话并发,https://learnku.com/articles/37476,2019-12-08 21:17:55,612,0,4<br />37738,三元运算符,https://learnku.com/articles/37738,2019-12-08 09:44:36,606,0,0<br />37719,笔试之 模板变量替换,https://learnku.com/articles/37719,2019-12-07 18:30:42,843,0,0<br />37707,笔试之 连续数增维,https://learnku.com/articles/37707,2019-12-07 13:50:17,872,0,0<br />37616,笔试之 一行代码求重,https://learnku.com/articles/37616,2019-12-05 12:10:24,792,0,0<br />....
Colly
Python网页爬虫&文本处理&科学计算&机器学习&数据挖掘兵器谱(转)
网站优化 • 优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2022-06-07 06:58
已获得授权
周末时看到这篇不错的文章,其中介绍了诸多python第三方库和工具,与大家分享下,也算是门可罗雀的本号第一次转载文章。后续看到精彩的文章也会继续分享。
Image Photograph by Pavliha Getty
曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python。
离开腾讯创业后,第一个作品课程图谱也是选择了Python系的Flask框架,渐渐的将自己的绝大部分工作交给了Python。这些年来,接触和使用了很多Python工具包,特别是在文本处理,科学计算,机器学习和数据挖掘领域,有很多很多优秀的Python工具包可供使用,所以作为Pythoner,也是相当幸福的。
其实如果仔细留意微博,你会发现很多这方面的分享,自己也Google了一下,发现也有同学总结了“Python机器学习库”,不过总感觉缺少点什么。最近流行一个词,全栈工程师(full stack engineer),作为一个苦逼的创业者,天然的要把自己打造成一个full stack engineer,而这个过程中,这些Python工具包给自己提供了足够的火力,所以想起了这个系列。
当然,这也仅仅是抛砖引玉,希望大家能提供更多的线索,来汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱。
一、Python网页爬虫工具集
一个真实的项目,一定是从获取数据开始的。无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,我们也就从这里开始了:
1.Scrapy
Scrapy, a fast high-level screen scraping and web crawling framework for Python.
鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课程都是依靠Scrapy抓去的,这方面的介绍文章有很多,推荐大牛pluskid早年的一篇文章:《Scrapy 轻松定制网络爬虫》,历久弥新。
官方主页:
Github代码页:
2.Beautiful Soup
You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
读书的时候通过《集体智慧编程》这本书知道Beautiful Soup的,后来也偶尔会用用,非常棒的一套工具。客观的说,Beautifu Soup不完全是一套爬虫工具,需要配合urllib使用,而是一套HTML/XML数据分析,清洗和获取工具。
官方主页:
3.Python-Goose
Html Content / Article Extractor, web scrapping lib in Python
Goose最早是用Java写得,后来用Scala重写,是一个Scala项目。Python-Goose用Python重写,依赖了Beautiful Soup。前段时间用过,感觉很不错,给定一个文章的URL, 获取文章的标题和内容很方便。
Github主页:
二、Python文本处理工具集
从网页上获取文本数据之后,依据任务的不同,就需要进行基本的文本处理了,譬如对于英文来说,需要基本的tokenize,对于中文,则需要常见的中文分词,进一步的话,无论英文中文,还可以词性标注,句法分析,关键词提取,文本分类,情感分析等等。这个方面,特别是面向英文领域,有很多优秀的工具包,我们一一道来。
1.NLTK— Natural Language Toolkit
NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
搞自然语言处理的同学应该没有人不知道NLTK吧,这里也就不多说了。不过推荐两本书籍给刚刚接触NLTK或者需要详细了解NLTK的同学: 一个是官方的《Natural Language Processing with Python》,以介绍NLTK里的功能用法为主,同时附带一些Python知识,同时国内陈涛同学友情翻译了一个中文版,这里可以看到:推荐《用Python进行自然语言处理》中文翻译-NLTK配套书;另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,这本书要深入一些,会涉及到NLTK的代码结构,同时会介绍如何定制自己的语料和模型等,相当不错。
官方主页:
Github代码页:
2.Pattern
Pattern is a web mining module for the Python programming language.
It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
Pattern由比利时安特卫普大学CLiPS实验室出品,客观的说,Pattern不仅仅是一套文本处理工具,它更是一套web数据挖掘工具,囊括了数据抓取模块(包括Google, Twitter, 维基百科的API,以及爬虫和HTML分析器),文本处理模块(词性标注,情感分析等),机器学习模块(VSM, 聚类,SVM)以及可视化模块等,可以说,Pattern的这一整套逻辑也是这篇文章的组织逻辑,不过这里我们暂且把Pattern放到文本处理部分。我个人主要使用的是它的英文处理模块Pattern.en, 有很多很不错的文本处理功能,包括基础的tokenize, 词性标注,句子切分,语法检查,拼写纠错,情感分析,句法分析等,相当不错。
官方主页:
3.TextBlob: Simplified Text Processing
TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
TextBlob是一个很有意思的Python文本处理工具包,它其实是基于上面两个Python工具包NLKT和Pattern做了封装(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同时提供了很多文本处理功能的接口,包括词性标注,名词短语提取,情感分析,文本分类,拼写检查等,甚至包括翻译和语言检测,不过这个是基于Google的API的,有调用次数限制。TextBlob相对比较年轻,有兴趣的同学可以关注。
官方主页:
Github代码页:
4.MBSPfor Python
MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
MBSP与Pattern同源,同出自比利时安特卫普大学CLiPS实验室,提供了Word Tokenization, 句子切分,词性标注,Chunking, Lemmatization,句法分析等基本的文本处理功能,感兴趣的同学可以关注。
官方主页:
5.Gensim: Topic modeling for humans
Gensim是一个相当专业的主题模型Python工具包,无论是代码还是文档,我们曾经用《如何计算两个文档的相似度》介绍过Gensim的安装和使用过程,这里就不多说了。
官方主页:
github代码页:
6.langid.py: Stand-alone language identification system
语言检测是一个很有意思的话题,不过相对比较成熟,这方面的解决方案很多,也有很多不错的开源工具包,不过对于Python来说,我使用过langid这个工具包,也非常愿意推荐它。langid目前支持97种语言的检测,提供了很多易用的功能,包括可以启动一个建议的server,通过json调用其API,可定制训练自己的语言检测模型等,可以说是“麻雀虽小,五脏俱全”。
Github主页:
7.Jieba: 结巴中文分词
“结巴”中文分词:做最好的Python中文分词组件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
好了,终于可以说一个国内的Python文本处理工具包了:结巴分词,其功能包括支持三种分词模式(精确模式、全模式、搜索引擎模式),支持繁体分词,支持自定义词典等,是目前一个非常不错的Python中文分词解决方案。
Github主页:
8.xTAS
xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
感谢微博朋友@大山坡的春提供的线索:我们组同事之前发布了xTAS,也是基于python的text mining工具包,欢迎使用,链接:。看起来很不错的样子,回头试用一下。
Github代码页:
三、Python科学计算工具包
说起科学计算,大家首先想起的是Matlab,集数值计算,可视化工具及交互于一身,不过可惜是一个商业产品。开源方面除了GNU Octave在尝试做一个类似Matlab的工具包外,Python的这几个工具包集合到一起也可以替代Matlab的相应功能:NumPy+SciPy+Matplotlib+iPython。同时,这几个工具包,特别是NumPy和SciPy,也是很多Python文本处理 & 机器学习 & 数据挖掘工具包的基础,非常重要。最后再推荐一个系列《用Python做科学计算》,将会涉及到NumPy, SciPy, Matplotlib,可以做参考。
1.NumPy
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
1)a powerful N-dimensional array object
2)sophisticated (broadcasting) functions
3)tools for integrating C/C++ and Fortran code
4) useful linear algebra, Fourier transform, and random number capabilities
Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
NumPy几乎是一个无法回避的科学计算工具包,最常用的也许是它的N维数组对象,其他还包括一些成熟的函数库,用于整合C/C++和Fortran代码的工具包,线性代数、傅里叶变换和随机数生成函数等。NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。
官方主页:
2.SciPy:Scientific Computing Tools for Python
SciPy refers to several related but distinct entities:
1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
2)The community of people who use and develop this stack.
3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
“SciPy是一个开源的Python算法库和数学工具包,SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。其功能与软件MATLAB、Scilab和GNU Octave类似。 Numpy和Scipy常常结合着使用,Python大多数机器学习库都依赖于这两个模块。”—-引用自“Python机器学习库”
官方主页:
3.Matplotlib
matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB®* or Mathematica®†), web application servers, and six graphical user interface toolkits.
matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。Matplotlib可以配合ipython shell使用,提供不亚于Matlab的绘图体验,总之用过了都说好。
官方主页:
4.iPython
IPython provides a rich architecture for interactive computing with:
1)Powerful interactive shells (terminal and Qt-based).
2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
3)Support for interactive data visualization and use of GUI toolkits.
4)Flexible, embeddable interpreters to load into your own projects.
5)Easy to use, high performance tools for parallel computing.
“iPython 是一个Python 的交互式Shell,比默认的Python Shell 好用得多,功能也更强大。 她支持语法高亮、自动完成、代码调试、对象自省,支持 Bash Shell 命令,内置了许多很有用的功能和函式等,非常容易使用。 ” 启动iPython的时候用这个命令“ipython –pylab”,默认开启了matploblib的绘图交互,用起来很方便。
官方主页:
四、Python 机器学习 & 数据挖掘 工具包
机器学习和数据挖掘这两个概念不太好区分,这里就放到一起了。这方面的开源Python工具包有很多,这里先从熟悉的讲起,再补充其他来源的资料,也欢迎大家补充。
1.scikit-learn: Machine Learning in Python
scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
首先推荐大名鼎鼎的scikit-learn,scikit-learn是一个基于NumPy, SciPy, Matplotlib的开源机器学习工具包,主要涵盖分类,回归和聚类算法,例如SVM, 逻辑回归,朴素贝叶斯,随机森林,k-means等算法,代码和文档都非常不错,在许多Python项目中都有应用。例如在我们熟悉的NLTK中,分类器方面就有专门针对scikit-learn的接口,可以调用scikit-learn的分类算法以及训练数据来训练分类器模型。这里推荐一个视频,也是我早期遇到scikit-learn的时候推荐过的:推荐一个Python机器学习工具包Scikit-learn以及相关视频–Tutorial: scikit-learn – Machine Learning in Python
官方主页:
2.Pandas: Python Data Analysis Library
Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
第一次接触Pandas是由于Udacity上的一门数据分析课程“Introduction to Data Science” 的Project需要用Pandas库,所以学习了一下Pandas。Pandas也是基于NumPy和Matplotlib开发的,主要用于数据分析和数据可视化,它的数据结构DataFrame和R语言里的data.frame很像,特别是对于时间序列数据有自己的一套分析机制,非常不错。这里推荐一本书《Python for Data Analysis》,作者是Pandas的主力开发,依次介绍了iPython, NumPy, Pandas里的相关功能,数据可视化,数据清洗和加工,时间数据处理等,案例包括金融股票数据挖掘等,相当不错。
官方主页:
=====================================================
分割线,以上工具包基本上都是自己用过的,以下来源于其他同学的线索,特别是《Python机器学习库》,《23个python的机器学习包》,做了一点增删修改,欢迎大家补充
=====================================================
3.mlpy – Machine Learning Python
mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
官方主页:
4.MDP:The Modular toolkit for Data Processing
Modular toolkit for Data Processing (MDP) is a Python data processing framework.
From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
“MDP用于数据处理的模块化工具包,一个Python数据处理框架。 从用户的观点,MDP是能够被整合到数据处理序列和更复杂的前馈网络结构的一批监督学习和非监督学习算法和其他数据处理单元。计算依照速度和内存需求而高效的执行。从科学开发者的观点,MDP是一个模块框架,它能够被容易地扩展。新算法的实现是容易且直观的。新实现的单元然后被自动地与程序库的其余部件进行整合。MDP在神经科学的理论研究背景下被编写,但是它已经被设计为在使用可训练数据处理算法的任何情况中都是有用的。其站在用户一边的简单性,各种不同的随时可用的算法,及应用单元的可重用性,使得它也是一个有用的教学工具。”
官方主页:
5.PyBrain
PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
“PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一个机器学习模块,它的目标是为机器学习任务提供灵活、易应、强大的机器学习算法。(这名字很霸气)
PyBrain正如其名,包括神经网络、强化学习(及二者结合)、无监督学习、进化算法。因为目前的许多问题需要处理连续态和行为空间,必须使用函数逼近(如神经网络)以应对高维数据。PyBrain以神经网络为核心,所有的训练方法都以神经网络为一个实例。”
官方主页:
6.PyML– machine learning in Python
PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
“PyML是一个Python机器学习工具包,为各分类和回归方法提供灵活的架构。它主要提供特征选择、模型选择、组合分类器、分类评估等功能。”
项目主页:
7.Milk:Machine learning toolkit in Python.
Its focus is on supervised classification with several classifiers available:
SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
feature selection. These classifiers can be combined in many ways to form
different classification systems.
“Milk是Python的一个机器学习工具箱,其重点是提供监督分类法与几种有效的分类分析:SVMs(基于libsvm),K-NN,随机森林经济和决策树。它还可以进行特征选择。这些分类可以在许多方面相结合,形成不同的分类系统。对于无监督学习,它提供K-means和affinity propagation聚类算法。”
官方主页:
8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
“PyMVPA(Multivariate Pattern Analysis in Python)是为大数据集提供统计学习分析的Python工具包,它提供了一个灵活可扩展的框架。它提供的功能有分类、回归、特征选择、数据导入导出、可视化等”
官方主页:
9.Pyrallel– Parallel Data Analytics in Python
Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
“Pyrallel(Parallel Data Analytics in Python)基于分布式计算模式的机器学习和半交互式的试验项目,可在小型集群上运行”
Github代码页:
10.Monte– gradient based learning in Python
Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
“Monte (machine learning in pure Python)是一个纯Python机器学习库。它可以迅速构建神经网络、条件随机场、逻辑回归等模型,使用inline-C优化,极易使用和扩展。”
官方主页:
11.Theano
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
5)dynamic C code generation – Evaluate expressions faster.
6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
“Theano 是一个 Python 库,用来定义、优化和模拟数学表达式计算,用于高效的解决多维数组的计算问题。Theano的特点:紧密集成Numpy;高效的数据密集型GPU计算;高效的符号微分运算;高速和稳定的优化;动态生成c代码;广泛的单元测试和自我验证。自2007年以来,Theano已被广泛应用于科学运算。theano使得构建深度学习模型更加容易,可以快速实现多种模型。PS:Theano,一位希腊美女,Croton最有权势的Milo的女儿,后来成为了毕达哥拉斯的老婆。”
12.Pylearn2
Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
“Pylearn2建立在theano上,部分依赖scikit-learn上,目前Pylearn2正处于开发中,将可以处理向量、图像、视频等数据,提供MLP、RBM、SDA等深度学习模型。”
官方主页:
其他的,欢迎大家补充。
欢迎关注“牛衣古柳”
门可罗雀,快来捕鸟!
查看全部
Python网页爬虫&文本处理&科学计算&机器学习&数据挖掘兵器谱(转)
已获得授权
周末时看到这篇不错的文章,其中介绍了诸多python第三方库和工具,与大家分享下,也算是门可罗雀的本号第一次转载文章。后续看到精彩的文章也会继续分享。
Image Photograph by Pavliha Getty
曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python。
离开腾讯创业后,第一个作品课程图谱也是选择了Python系的Flask框架,渐渐的将自己的绝大部分工作交给了Python。这些年来,接触和使用了很多Python工具包,特别是在文本处理,科学计算,机器学习和数据挖掘领域,有很多很多优秀的Python工具包可供使用,所以作为Pythoner,也是相当幸福的。
其实如果仔细留意微博,你会发现很多这方面的分享,自己也Google了一下,发现也有同学总结了“Python机器学习库”,不过总感觉缺少点什么。最近流行一个词,全栈工程师(full stack engineer),作为一个苦逼的创业者,天然的要把自己打造成一个full stack engineer,而这个过程中,这些Python工具包给自己提供了足够的火力,所以想起了这个系列。
当然,这也仅仅是抛砖引玉,希望大家能提供更多的线索,来汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱。
一、Python网页爬虫工具集
一个真实的项目,一定是从获取数据开始的。无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,我们也就从这里开始了:
1.Scrapy
Scrapy, a fast high-level screen scraping and web crawling framework for Python.
鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课程都是依靠Scrapy抓去的,这方面的介绍文章有很多,推荐大牛pluskid早年的一篇文章:《Scrapy 轻松定制网络爬虫》,历久弥新。
官方主页:
Github代码页:
2.Beautiful Soup
You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help. Since 2004, it’s been saving programmers hours or days of work on quick-turnaround screen scraping projects.
读书的时候通过《集体智慧编程》这本书知道Beautiful Soup的,后来也偶尔会用用,非常棒的一套工具。客观的说,Beautifu Soup不完全是一套爬虫工具,需要配合urllib使用,而是一套HTML/XML数据分析,清洗和获取工具。
官方主页:
3.Python-Goose
Html Content / Article Extractor, web scrapping lib in Python
Goose最早是用Java写得,后来用Scala重写,是一个Scala项目。Python-Goose用Python重写,依赖了Beautiful Soup。前段时间用过,感觉很不错,给定一个文章的URL, 获取文章的标题和内容很方便。
Github主页:
二、Python文本处理工具集
从网页上获取文本数据之后,依据任务的不同,就需要进行基本的文本处理了,譬如对于英文来说,需要基本的tokenize,对于中文,则需要常见的中文分词,进一步的话,无论英文中文,还可以词性标注,句法分析,关键词提取,文本分类,情感分析等等。这个方面,特别是面向英文领域,有很多优秀的工具包,我们一一道来。
1.NLTK— Natural Language Toolkit
NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, and an active discussion forum.
搞自然语言处理的同学应该没有人不知道NLTK吧,这里也就不多说了。不过推荐两本书籍给刚刚接触NLTK或者需要详细了解NLTK的同学: 一个是官方的《Natural Language Processing with Python》,以介绍NLTK里的功能用法为主,同时附带一些Python知识,同时国内陈涛同学友情翻译了一个中文版,这里可以看到:推荐《用Python进行自然语言处理》中文翻译-NLTK配套书;另外一本是《Python Text Processing with NLTK 2.0 Cookbook》,这本书要深入一些,会涉及到NLTK的代码结构,同时会介绍如何定制自己的语料和模型等,相当不错。
官方主页:
Github代码页:
2.Pattern
Pattern is a web mining module for the Python programming language.
It has tools for data mining (Google, Twitter and Wikipedia API, a web crawler, a HTML DOM parser), natural language processing (part-of-speech taggers, n-gram search, sentiment analysis, WordNet), machine learning (vector space model, clustering, SVM), network analysis and canvas visualization.
Pattern由比利时安特卫普大学CLiPS实验室出品,客观的说,Pattern不仅仅是一套文本处理工具,它更是一套web数据挖掘工具,囊括了数据抓取模块(包括Google, Twitter, 维基百科的API,以及爬虫和HTML分析器),文本处理模块(词性标注,情感分析等),机器学习模块(VSM, 聚类,SVM)以及可视化模块等,可以说,Pattern的这一整套逻辑也是这篇文章的组织逻辑,不过这里我们暂且把Pattern放到文本处理部分。我个人主要使用的是它的英文处理模块Pattern.en, 有很多很不错的文本处理功能,包括基础的tokenize, 词性标注,句子切分,语法检查,拼写纠错,情感分析,句法分析等,相当不错。
官方主页:
3.TextBlob: Simplified Text Processing
TextBlob is a Python (2 and 3) library for processing textual data. It provides a simple API for diving into common natural language processing (NLP) tasks such as part-of-speech tagging, noun phrase extraction, sentiment analysis, classification, translation, and more.
TextBlob是一个很有意思的Python文本处理工具包,它其实是基于上面两个Python工具包NLKT和Pattern做了封装(TextBlob stands on the giant shoulders of NLTK and pattern, and plays nicely with both),同时提供了很多文本处理功能的接口,包括词性标注,名词短语提取,情感分析,文本分类,拼写检查等,甚至包括翻译和语言检测,不过这个是基于Google的API的,有调用次数限制。TextBlob相对比较年轻,有兴趣的同学可以关注。
官方主页:
Github代码页:
4.MBSPfor Python
MBSP is a text analysis system based on the TiMBL and MBT memory based learning applications developed at CLiPS and ILK. It provides tools for Tokenization and Sentence Splitting, Part of Speech Tagging, Chunking, Lemmatization, Relation Finding and Prepositional Phrase Attachment.
MBSP与Pattern同源,同出自比利时安特卫普大学CLiPS实验室,提供了Word Tokenization, 句子切分,词性标注,Chunking, Lemmatization,句法分析等基本的文本处理功能,感兴趣的同学可以关注。
官方主页:
5.Gensim: Topic modeling for humans
Gensim是一个相当专业的主题模型Python工具包,无论是代码还是文档,我们曾经用《如何计算两个文档的相似度》介绍过Gensim的安装和使用过程,这里就不多说了。
官方主页:
github代码页:
6.langid.py: Stand-alone language identification system
语言检测是一个很有意思的话题,不过相对比较成熟,这方面的解决方案很多,也有很多不错的开源工具包,不过对于Python来说,我使用过langid这个工具包,也非常愿意推荐它。langid目前支持97种语言的检测,提供了很多易用的功能,包括可以启动一个建议的server,通过json调用其API,可定制训练自己的语言检测模型等,可以说是“麻雀虽小,五脏俱全”。
Github主页:
7.Jieba: 结巴中文分词
“结巴”中文分词:做最好的Python中文分词组件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module.
好了,终于可以说一个国内的Python文本处理工具包了:结巴分词,其功能包括支持三种分词模式(精确模式、全模式、搜索引擎模式),支持繁体分词,支持自定义词典等,是目前一个非常不错的Python中文分词解决方案。
Github主页:
8.xTAS
xtas, the eXtensible Text Analysis Suite, a distributed text analysis package based on Celery and Elasticsearch.
感谢微博朋友@大山坡的春提供的线索:我们组同事之前发布了xTAS,也是基于python的text mining工具包,欢迎使用,链接:。看起来很不错的样子,回头试用一下。
Github代码页:
三、Python科学计算工具包
说起科学计算,大家首先想起的是Matlab,集数值计算,可视化工具及交互于一身,不过可惜是一个商业产品。开源方面除了GNU Octave在尝试做一个类似Matlab的工具包外,Python的这几个工具包集合到一起也可以替代Matlab的相应功能:NumPy+SciPy+Matplotlib+iPython。同时,这几个工具包,特别是NumPy和SciPy,也是很多Python文本处理 & 机器学习 & 数据挖掘工具包的基础,非常重要。最后再推荐一个系列《用Python做科学计算》,将会涉及到NumPy, SciPy, Matplotlib,可以做参考。
1.NumPy
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
1)a powerful N-dimensional array object
2)sophisticated (broadcasting) functions
3)tools for integrating C/C++ and Fortran code
4) useful linear algebra, Fourier transform, and random number capabilities
Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
NumPy几乎是一个无法回避的科学计算工具包,最常用的也许是它的N维数组对象,其他还包括一些成熟的函数库,用于整合C/C++和Fortran代码的工具包,线性代数、傅里叶变换和随机数生成函数等。NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。
官方主页:
2.SciPy:Scientific Computing Tools for Python
SciPy refers to several related but distinct entities:
1)The SciPy Stack, a collection of open source software for scientific computing in Python, and particularly a specified set of core packages.
2)The community of people who use and develop this stack.
3)Several conferences dedicated to scientific computing in Python – SciPy, EuroSciPy and SciPy.in.
4)The SciPy library, one component of the SciPy stack, providing many numerical routines.
“SciPy是一个开源的Python算法库和数学工具包,SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。其功能与软件MATLAB、Scilab和GNU Octave类似。 Numpy和Scipy常常结合着使用,Python大多数机器学习库都依赖于这两个模块。”—-引用自“Python机器学习库”
官方主页:
3.Matplotlib
matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB®* or Mathematica®†), web application servers, and six graphical user interface toolkits.
matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。Matplotlib可以配合ipython shell使用,提供不亚于Matlab的绘图体验,总之用过了都说好。
官方主页:
4.iPython
IPython provides a rich architecture for interactive computing with:
1)Powerful interactive shells (terminal and Qt-based).
2)A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
3)Support for interactive data visualization and use of GUI toolkits.
4)Flexible, embeddable interpreters to load into your own projects.
5)Easy to use, high performance tools for parallel computing.
“iPython 是一个Python 的交互式Shell,比默认的Python Shell 好用得多,功能也更强大。 她支持语法高亮、自动完成、代码调试、对象自省,支持 Bash Shell 命令,内置了许多很有用的功能和函式等,非常容易使用。 ” 启动iPython的时候用这个命令“ipython –pylab”,默认开启了matploblib的绘图交互,用起来很方便。
官方主页:
四、Python 机器学习 & 数据挖掘 工具包
机器学习和数据挖掘这两个概念不太好区分,这里就放到一起了。这方面的开源Python工具包有很多,这里先从熟悉的讲起,再补充其他来源的资料,也欢迎大家补充。
1.scikit-learn: Machine Learning in Python
scikit-learn (formerly scikits.learn) is an open source machine learning library for the Python programming language. It features various classification, regression and clustering algorithms including support vector machines, logistic regression, naive Bayes, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.
首先推荐大名鼎鼎的scikit-learn,scikit-learn是一个基于NumPy, SciPy, Matplotlib的开源机器学习工具包,主要涵盖分类,回归和聚类算法,例如SVM, 逻辑回归,朴素贝叶斯,随机森林,k-means等算法,代码和文档都非常不错,在许多Python项目中都有应用。例如在我们熟悉的NLTK中,分类器方面就有专门针对scikit-learn的接口,可以调用scikit-learn的分类算法以及训练数据来训练分类器模型。这里推荐一个视频,也是我早期遇到scikit-learn的时候推荐过的:推荐一个Python机器学习工具包Scikit-learn以及相关视频–Tutorial: scikit-learn – Machine Learning in Python
官方主页:
2.Pandas: Python Data Analysis Library
Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series.
第一次接触Pandas是由于Udacity上的一门数据分析课程“Introduction to Data Science” 的Project需要用Pandas库,所以学习了一下Pandas。Pandas也是基于NumPy和Matplotlib开发的,主要用于数据分析和数据可视化,它的数据结构DataFrame和R语言里的data.frame很像,特别是对于时间序列数据有自己的一套分析机制,非常不错。这里推荐一本书《Python for Data Analysis》,作者是Pandas的主力开发,依次介绍了iPython, NumPy, Pandas里的相关功能,数据可视化,数据清洗和加工,时间数据处理等,案例包括金融股票数据挖掘等,相当不错。
官方主页:
=====================================================
分割线,以上工具包基本上都是自己用过的,以下来源于其他同学的线索,特别是《Python机器学习库》,《23个python的机器学习包》,做了一点增删修改,欢迎大家补充
=====================================================
3.mlpy – Machine Learning Python
mlpy is a Python module for Machine Learning built on top of NumPy/SciPy and the GNU Scientific Libraries.
mlpy provides a wide range of state-of-the-art machine learning methods for supervised and unsupervised problems and it is aimed at finding a reasonable compromise among modularity, maintainability, reproducibility, usability and efficiency. mlpy is multiplatform, it works with Python 2 and 3 and it is Open Source, distributed under the GNU General Public License version 3.
官方主页:
4.MDP:The Modular toolkit for Data Processing
Modular toolkit for Data Processing (MDP) is a Python data processing framework.
From the user’s perspective, MDP is a collection of supervised and unsupervised learning algorithms and other data processing units that can be combined into data processing sequences and more complex feed-forward network architectures.
From the scientific developer’s perspective, MDP is a modular framework, which can easily be expanded. The implementation of new algorithms is easy and intuitive. The new implemented units are then automatically integrated with the rest of the library.
The base of available algorithms is steadily increasing and includes signal processing methods (Principal Component Analysis, Independent Component Analysis, Slow Feature Analysis), manifold learning methods ([Hessian] Locally Linear Embedding), several classifiers, probabilistic methods (Factor Analysis, RBM), data pre-processing methods, and many others.
“MDP用于数据处理的模块化工具包,一个Python数据处理框架。 从用户的观点,MDP是能够被整合到数据处理序列和更复杂的前馈网络结构的一批监督学习和非监督学习算法和其他数据处理单元。计算依照速度和内存需求而高效的执行。从科学开发者的观点,MDP是一个模块框架,它能够被容易地扩展。新算法的实现是容易且直观的。新实现的单元然后被自动地与程序库的其余部件进行整合。MDP在神经科学的理论研究背景下被编写,但是它已经被设计为在使用可训练数据处理算法的任何情况中都是有用的。其站在用户一边的简单性,各种不同的随时可用的算法,及应用单元的可重用性,使得它也是一个有用的教学工具。”
官方主页:
5.PyBrain
PyBrain is a modular Machine Learning Library for Python. Its goal is to offer flexible, easy-to-use yet still powerful algorithms for Machine Learning Tasks and a variety of predefined environments to test and compare your algorithms.
PyBrain is short for Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network Library. In fact, we came up with the name first and later reverse-engineered this quite descriptive “Backronym”.
“PyBrain(Python-Based Reinforcement Learning, Artificial Intelligence and Neural Network)是Python的一个机器学习模块,它的目标是为机器学习任务提供灵活、易应、强大的机器学习算法。(这名字很霸气)
PyBrain正如其名,包括神经网络、强化学习(及二者结合)、无监督学习、进化算法。因为目前的许多问题需要处理连续态和行为空间,必须使用函数逼近(如神经网络)以应对高维数据。PyBrain以神经网络为核心,所有的训练方法都以神经网络为一个实例。”
官方主页:
6.PyML– machine learning in Python
PyML is an interactive object oriented framework for machine learning written in Python. PyML focuses on SVMs and other kernel methods. It is supported on Linux and Mac OS X.
“PyML是一个Python机器学习工具包,为各分类和回归方法提供灵活的架构。它主要提供特征选择、模型选择、组合分类器、分类评估等功能。”
项目主页:
7.Milk:Machine learning toolkit in Python.
Its focus is on supervised classification with several classifiers available:
SVMs (based on libsvm), k-NN, random forests, decision trees. It also performs
feature selection. These classifiers can be combined in many ways to form
different classification systems.
“Milk是Python的一个机器学习工具箱,其重点是提供监督分类法与几种有效的分类分析:SVMs(基于libsvm),K-NN,随机森林经济和决策树。它还可以进行特征选择。这些分类可以在许多方面相结合,形成不同的分类系统。对于无监督学习,它提供K-means和affinity propagation聚类算法。”
官方主页:
8.PyMVPA: MultiVariate Pattern Analysis (MVPA) in Python
PyMVPA is a Python package intended to ease statistical learning analyses of large datasets. It offers an extensible framework with a high-level interface to a broad range of algorithms for classification, regression, feature selection, data import and export. It is designed to integrate well with related software packages, such as scikit-learn, and MDP. While it is not limited to the neuroimaging domain, it is eminently suited for such datasets. PyMVPA is free software and requires nothing but free-software to run.
“PyMVPA(Multivariate Pattern Analysis in Python)是为大数据集提供统计学习分析的Python工具包,它提供了一个灵活可扩展的框架。它提供的功能有分类、回归、特征选择、数据导入导出、可视化等”
官方主页:
9.Pyrallel– Parallel Data Analytics in Python
Experimental project to investigate distributed computation patterns for machine learning and other semi-interactive data analytics tasks.
“Pyrallel(Parallel Data Analytics in Python)基于分布式计算模式的机器学习和半交互式的试验项目,可在小型集群上运行”
Github代码页:
10.Monte– gradient based learning in Python
Monte (python) is a Python framework for building gradient based learning machines, like neural networks, conditional random fields, logistic regression, etc. Monte contains modules (that hold parameters, a cost-function and a gradient-function) and trainers (that can adapt a module’s parameters by minimizing its cost-function on training data).
Modules are usually composed of other modules, which can in turn contain other modules, etc. Gradients of decomposable systems like these can be computed with back-propagation.
“Monte (machine learning in pure Python)是一个纯Python机器学习库。它可以迅速构建神经网络、条件随机场、逻辑回归等模型,使用inline-C优化,极易使用和扩展。”
官方主页:
11.Theano
Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. Theano features:
1)tight integration with NumPy – Use numpy.ndarray in Theano-compiled functions.
2)transparent use of a GPU – Perform data-intensive calculations up to 140x faster than with CPU.(float32 only)
3)efficient symbolic differentiation – Theano does your derivatives for function with one or many inputs.
4)speed and stability optimizations – Get the right answer for log(1+x) even when x is really tiny.
5)dynamic C code generation – Evaluate expressions faster.
6) extensive unit-testing and self-verification – Detect and diagnose many types of mistake.
Theano has been powering large-scale computationally intensive scientific investigations since 2007. But it is also approachable enough to be used in the classroom (IFT6266 at the University of Montreal).
“Theano 是一个 Python 库,用来定义、优化和模拟数学表达式计算,用于高效的解决多维数组的计算问题。Theano的特点:紧密集成Numpy;高效的数据密集型GPU计算;高效的符号微分运算;高速和稳定的优化;动态生成c代码;广泛的单元测试和自我验证。自2007年以来,Theano已被广泛应用于科学运算。theano使得构建深度学习模型更加容易,可以快速实现多种模型。PS:Theano,一位希腊美女,Croton最有权势的Milo的女儿,后来成为了毕达哥拉斯的老婆。”
12.Pylearn2
Pylearn2 is a machine learning library. Most of its functionality is built on top of Theano. This means you can write Pylearn2 plugins (new models, algorithms, etc) using mathematical expressions, and theano will optimize and stabilize those expressions for you, and compile them to a backend of your choice (CPU or GPU).
“Pylearn2建立在theano上,部分依赖scikit-learn上,目前Pylearn2正处于开发中,将可以处理向量、图像、视频等数据,提供MLP、RBM、SDA等深度学习模型。”
官方主页:
其他的,欢迎大家补充。
欢迎关注“牛衣古柳”
门可罗雀,快来捕鸟!
如何用C/C++写一个基于事件的爬虫
网站优化 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-06-06 17:06
在去年三月份的时候,写过一篇文章,讲了一下如何写一个知乎爬虫,爬下最高票的答案,并且把代码放到了github,。在这一年多的时间里,前前后后有很多人来问我关于这个爬虫的一些实现细节,在回答他们的同时发现自己原来的代码真是写得太烂了,最近正好有空,把代码和架构都重写了一下,不能再误人子弟了。
所以有了这篇文章,记录下自己的一些改进,以及尽可能说清楚如何用C++实现一个高性能爬虫。
为什么要用C++写
在继续往下看之前一定要先想清楚一个问题,现在用Python或者NodeJS可以非常快速地开发出一个爬虫,库齐全,开发成本非常低,那为什么还要用C来写爬虫?答案是这要看你的目的。如果你单纯是为了完成一个数据抓取的任务,当然是任务完成得越快越好,以后代码越好修改越好,首选就是那些库齐全的动态语言,但如果你的目的是为了理解底层系统,理解抓取数据的每一个环节,那么我的推荐是用C++写吧,并且所有轮子都自己造。我的目的是后者,所以选择了用C来写。既然所有轮子都自己造了,那这篇文章应该叫,如何不用任何第三方库,只用C/C++内建函数来完成一个网络爬虫。
用Python写会是什么样子?有Requests库来封装HTTP请求,有BeautifulSoup来解析HTML,大大减少了开发难度,你只需要知道爬虫的一般流程,很容易写出一个能跑的代码,用NodeJS也是一样的。
知乎爬虫原理
如果有读者不太清楚爬虫的原理,请先看一下这篇入门文章。
接下来简单说一个我的zhihu爬虫的原理,因为我的目标是爬下最高赞/最高关注这些类型的答案和问题,所以从用户主页出发是最好不过的,比如从用户主页点击“回答”,就可以看到用户的所有回答,然后抓下来,点击“提问”,就可以看到用户所有的提问。把所有用户的所有回答/提问都抓下来然后根据点赞数/关注数排序,就是我想要的结果。那所有用户怎么得到?从一个用户出发(即队列中的初始URL),把TA的所有关注的人和关注者都爬下来,不重复地放入URL队列中,等到当前用户处理完,再从URL队列里拿下一个用户,如此循环即可。
仔细想想,这个方法会有一个问题,如果一个人即不关注别人也不被别人关注,且不在初始URL队列中,那么这个用户的回答和提问永远不会被抓到。更一般的结论是,如果有用户群构成“孤岛”,那么这些用户群都不会被爬虫访问。举个例子,A、B互相关注,C、D互相关注,如果我们将A放入初始URL队列,那么爬虫只可能抓下A、B的数据,因为C、D构成了“孤岛”,怎么解决这个问题?
再想想,这个问题真的有必要解决吗?这个问题会对我们造成困扰的情况是,一个大V答了一个赞数很高的问题,但是TA竟然在某座“孤岛”上,如果我们称大部分人所构成的连通图叫主图,那么这个大V构成的“孤岛”和主图上的人一点关系都没有,即不被关注也不关注别人,这几乎是不可能的事情,所以这个问题不需要解决。
如何用C++写爬虫
无论用Python或者C++写爬虫,底层都是一样的,都是和server建立若干个TCP连接,然后把HTTP请求写入这个TCP socket中,等待server的数据返回。为了高效处理I/O,在linux平台下需要用epoll(别的平台请用各自的机制)。
所以一个C++爬虫步骤大概是这样的,本质上就是一个事件循环(event loop):
初始化epoll,并和server建立TCP连接
从URL队列中拿出url,并准备好http请求
将http请求写入到这个TCP socket中,并把这个socket加入epoll中
检查活动事件(epoll_wait)
处理事件,读取HTML,解析HTML,处理HTML,然后把相关未处理过的URL放入URL队列中
回到第2步
原来的代码结构
先简单描述一下去年写的爬虫代码是怎么误人子弟的。
程序从队列里拿到一个URL后,需要去下载这个URL的页面,解析出我需要的数据,然后把它的下一层URL加入队列中。原来的爬虫代码就老老实实地实现了这个步骤,阻塞地等待页面下载完成,再去处理这个页面。其实这是很低效的,因为阻塞的这段时期我们什么都干不了,浪费了带宽。为什么不把队列里的其它URL请求一起发出去呢,然后有数据来了我就处理。这就是为什么爬虫为什么要用基于事件来写的原因。
这里需要理解爬虫这种程序的本质,它是网络I/O密集程序,不是CPU密集,而处理I/O密集最高效的做法就是事件循环。
所以我做的一个做大的改善就是把原来的阻塞爬虫改成了基于事件的爬虫,它得到的好处是可以完全把带宽跑满,爬取速度最大化。
除此之外,还有一个改善是把多线程模型改成了单进程模型。有同学可能会产生疑惑,难道利用多核还会比单核性能差?我们从以下两点来分析:
根据amdahl定律,对系统中一个模块的加速,不仅取决于加速比,还取决于这个模块在原来系统中占的比例。爬虫是I/O密集程序,绝大部分时间都花在了网络I/O上,CPU大部分时间是空闲的,所以提高CPU的利用率其实效果很小。
多线程会引入额外的开销,最大的开销可能就是锁了。比如你要把新的URL加入队列,这时候在多线程环境下肯定要对队列加锁。
那么问题就是,第一点所带来的性能提升和第二点所带来的开销,哪个更大一点?如果第二点大,我们果断要换成单进程。答案是看环境,我们极端点看,如果你的带宽无穷大,网络情况无穷好,那么请求一发出去立刻就回复了,这个网络I/O密集程序硬生生变成了CPU密集,多线程会好;如果你的带宽无穷小,那么锁带来的开销会占比更大,一个任务来了多线程之间还要竞争一下,单线程就直接处理了且没有锁的性能开销,用单线程会好。我们需要在不同的环境下选择最好的办法,不过一般来说,现实中最大的时间开销一定在网络I/O。
用C++实现爬虫时的难点
从TCP socket读取数据到把完整的HTML数据交付上层需要一个数据层,因为如果调用read返回EAGAIN时,这时是不知道到底有没有接受到完整的HTML,需要保存好当前读到的网页内容,并通过一个状态机来解析当前收到的数据,保存当前的状态,如果解析完成(读到全部数据了)就返回SUCCESS,否则就就返回ERROR,等待下一次数据来临,继续解析状态机。用动态语言不需要考虑这一点,会直接传递给用户层完整的数据。
请求得太快,知乎会返回429错误(即提示客户请求太多,稍后再试),这个问题怎么解决?乖乖地等待一段时间再去抓是一种浪费带宽的行为。服务器判断请求太多是看这个IP在一段时间的请求数太多了,如果我们IP分散为N个不同IP,那就解决这个问题了。这个方案叫动态IP或者代理IP。那么多IP意味着要花很多的钱,如果不愿意花钱,还是乖乖等一段时间再发请求吧。
爬虫里一个需求,要获得一个用户的所有关注的人和关注者,但这些东西都是通过ajax获取的,所以要写一个post请求来模拟ajax。其中post data里有一个hash_id和_xsrf,这两个值都在哪里可以获得?后来在该用户的主页的HTML里找到了这两个值。
怎么用C++解析HTML?比如上面一点提到的,我要找到这个页面里的hash_id,它可能是某个HTML元素的属性,怎么得到这个属性值?用过JQuery的同学这时会想,如果C++里面也有一个像JQuery那么好用的库该多好,直接写个选择器就获得属性的值了。我简单地调研了一下,C++还是有这样的库的。基于学习的目的,最好自己写一个这样的库,所以,问题来了,怎么实现一个HTML parser?或者更简单的,怎么实现一个正则匹配?
如何管理一个请求的周期,因为一个请求的周期中,状态太多了。为什么状态多,因为一个请求会涉及很多异步操作,首先获取该用户的答案页面,这时候要等待server的回复,处理完以后获得改用户所有关注的人和关注者的页面,也要等待server的回复,再把这些所有用户加入队列后,这个请求周期才算结束。
需要自己处理一些HTTP header的细节。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回复,因为它显然没有Content-length直接获取到数据长度来得方便,该怎么办?再比如不希望接受到gzip处理过的数据,希望收到plain text,又该怎么办?
架构怎么设计。首先最底层是TCP层,上层应该封装一个数据接收层,再上层应该是HTML解析层,最后是事件循环层。这些层次/模块怎么做到耦合度最低?
网络异常怎么处理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一个新的连接,然后继续前一个请求(或者说继续状态机)。
用C++相比Python,NodeJS的优点
系统的掌控性。比如我们希望TCP连接数要控制在1000,完全可能很容易地实现。并且可以知道哪里会耗内存、CPU,底层在发生什么我们更容易知道。比如,在HTTP request header里写上Connection: keep-alive可以让很多请求复用一个TCP连接,在用C++实现的时候,对应的实现方法很简单粗暴:从socket读完对方服务器发来的response后,再构造一个header发过去即可。
因为一些内建库的缺乏,并且出发点是学习,我们会重新造一些轮子,与此同时,提高了编程能力。 比如说读配置文件,格式是json,可以自己用C写个json parser。再比如上文提到的HTML parser,也可以用C写一个,还有基于epoll的事件循环,可以抽象成一个通用的网络库。有太多轮子可以造,要把其中任意一个轮子写好都是非常难的事情。
高性能。可能由于网络的大延迟使得这个优点不那么明显。
总结
本文基于我一年多之前写的zhihu爬虫以及最近的大规模改进,总结了如何用C++编写的高效、基于事件驱动的知乎爬虫,同时也列出了用C++写爬虫时的一些难点与收获。
如果你有兴趣看看竟然有人用C++写了一个爬虫究竟是什么样子的,代码在这里。
. END.
看完本文请分享一下吧!让其他人也可以GET到新知识!
查看全部
如何用C/C++写一个基于事件的爬虫
在去年三月份的时候,写过一篇文章,讲了一下如何写一个知乎爬虫,爬下最高票的答案,并且把代码放到了github,。在这一年多的时间里,前前后后有很多人来问我关于这个爬虫的一些实现细节,在回答他们的同时发现自己原来的代码真是写得太烂了,最近正好有空,把代码和架构都重写了一下,不能再误人子弟了。
所以有了这篇文章,记录下自己的一些改进,以及尽可能说清楚如何用C++实现一个高性能爬虫。
为什么要用C++写
在继续往下看之前一定要先想清楚一个问题,现在用Python或者NodeJS可以非常快速地开发出一个爬虫,库齐全,开发成本非常低,那为什么还要用C来写爬虫?答案是这要看你的目的。如果你单纯是为了完成一个数据抓取的任务,当然是任务完成得越快越好,以后代码越好修改越好,首选就是那些库齐全的动态语言,但如果你的目的是为了理解底层系统,理解抓取数据的每一个环节,那么我的推荐是用C++写吧,并且所有轮子都自己造。我的目的是后者,所以选择了用C来写。既然所有轮子都自己造了,那这篇文章应该叫,如何不用任何第三方库,只用C/C++内建函数来完成一个网络爬虫。
用Python写会是什么样子?有Requests库来封装HTTP请求,有BeautifulSoup来解析HTML,大大减少了开发难度,你只需要知道爬虫的一般流程,很容易写出一个能跑的代码,用NodeJS也是一样的。
知乎爬虫原理
如果有读者不太清楚爬虫的原理,请先看一下这篇入门文章。
接下来简单说一个我的zhihu爬虫的原理,因为我的目标是爬下最高赞/最高关注这些类型的答案和问题,所以从用户主页出发是最好不过的,比如从用户主页点击“回答”,就可以看到用户的所有回答,然后抓下来,点击“提问”,就可以看到用户所有的提问。把所有用户的所有回答/提问都抓下来然后根据点赞数/关注数排序,就是我想要的结果。那所有用户怎么得到?从一个用户出发(即队列中的初始URL),把TA的所有关注的人和关注者都爬下来,不重复地放入URL队列中,等到当前用户处理完,再从URL队列里拿下一个用户,如此循环即可。
仔细想想,这个方法会有一个问题,如果一个人即不关注别人也不被别人关注,且不在初始URL队列中,那么这个用户的回答和提问永远不会被抓到。更一般的结论是,如果有用户群构成“孤岛”,那么这些用户群都不会被爬虫访问。举个例子,A、B互相关注,C、D互相关注,如果我们将A放入初始URL队列,那么爬虫只可能抓下A、B的数据,因为C、D构成了“孤岛”,怎么解决这个问题?
再想想,这个问题真的有必要解决吗?这个问题会对我们造成困扰的情况是,一个大V答了一个赞数很高的问题,但是TA竟然在某座“孤岛”上,如果我们称大部分人所构成的连通图叫主图,那么这个大V构成的“孤岛”和主图上的人一点关系都没有,即不被关注也不关注别人,这几乎是不可能的事情,所以这个问题不需要解决。
如何用C++写爬虫
无论用Python或者C++写爬虫,底层都是一样的,都是和server建立若干个TCP连接,然后把HTTP请求写入这个TCP socket中,等待server的数据返回。为了高效处理I/O,在linux平台下需要用epoll(别的平台请用各自的机制)。
所以一个C++爬虫步骤大概是这样的,本质上就是一个事件循环(event loop):
初始化epoll,并和server建立TCP连接
从URL队列中拿出url,并准备好http请求
将http请求写入到这个TCP socket中,并把这个socket加入epoll中
检查活动事件(epoll_wait)
处理事件,读取HTML,解析HTML,处理HTML,然后把相关未处理过的URL放入URL队列中
回到第2步
原来的代码结构
先简单描述一下去年写的爬虫代码是怎么误人子弟的。
程序从队列里拿到一个URL后,需要去下载这个URL的页面,解析出我需要的数据,然后把它的下一层URL加入队列中。原来的爬虫代码就老老实实地实现了这个步骤,阻塞地等待页面下载完成,再去处理这个页面。其实这是很低效的,因为阻塞的这段时期我们什么都干不了,浪费了带宽。为什么不把队列里的其它URL请求一起发出去呢,然后有数据来了我就处理。这就是为什么爬虫为什么要用基于事件来写的原因。
这里需要理解爬虫这种程序的本质,它是网络I/O密集程序,不是CPU密集,而处理I/O密集最高效的做法就是事件循环。
所以我做的一个做大的改善就是把原来的阻塞爬虫改成了基于事件的爬虫,它得到的好处是可以完全把带宽跑满,爬取速度最大化。
除此之外,还有一个改善是把多线程模型改成了单进程模型。有同学可能会产生疑惑,难道利用多核还会比单核性能差?我们从以下两点来分析:
根据amdahl定律,对系统中一个模块的加速,不仅取决于加速比,还取决于这个模块在原来系统中占的比例。爬虫是I/O密集程序,绝大部分时间都花在了网络I/O上,CPU大部分时间是空闲的,所以提高CPU的利用率其实效果很小。
多线程会引入额外的开销,最大的开销可能就是锁了。比如你要把新的URL加入队列,这时候在多线程环境下肯定要对队列加锁。
那么问题就是,第一点所带来的性能提升和第二点所带来的开销,哪个更大一点?如果第二点大,我们果断要换成单进程。答案是看环境,我们极端点看,如果你的带宽无穷大,网络情况无穷好,那么请求一发出去立刻就回复了,这个网络I/O密集程序硬生生变成了CPU密集,多线程会好;如果你的带宽无穷小,那么锁带来的开销会占比更大,一个任务来了多线程之间还要竞争一下,单线程就直接处理了且没有锁的性能开销,用单线程会好。我们需要在不同的环境下选择最好的办法,不过一般来说,现实中最大的时间开销一定在网络I/O。
用C++实现爬虫时的难点
从TCP socket读取数据到把完整的HTML数据交付上层需要一个数据层,因为如果调用read返回EAGAIN时,这时是不知道到底有没有接受到完整的HTML,需要保存好当前读到的网页内容,并通过一个状态机来解析当前收到的数据,保存当前的状态,如果解析完成(读到全部数据了)就返回SUCCESS,否则就就返回ERROR,等待下一次数据来临,继续解析状态机。用动态语言不需要考虑这一点,会直接传递给用户层完整的数据。
请求得太快,知乎会返回429错误(即提示客户请求太多,稍后再试),这个问题怎么解决?乖乖地等待一段时间再去抓是一种浪费带宽的行为。服务器判断请求太多是看这个IP在一段时间的请求数太多了,如果我们IP分散为N个不同IP,那就解决这个问题了。这个方案叫动态IP或者代理IP。那么多IP意味着要花很多的钱,如果不愿意花钱,还是乖乖等一段时间再发请求吧。
爬虫里一个需求,要获得一个用户的所有关注的人和关注者,但这些东西都是通过ajax获取的,所以要写一个post请求来模拟ajax。其中post data里有一个hash_id和_xsrf,这两个值都在哪里可以获得?后来在该用户的主页的HTML里找到了这两个值。
怎么用C++解析HTML?比如上面一点提到的,我要找到这个页面里的hash_id,它可能是某个HTML元素的属性,怎么得到这个属性值?用过JQuery的同学这时会想,如果C++里面也有一个像JQuery那么好用的库该多好,直接写个选择器就获得属性的值了。我简单地调研了一下,C++还是有这样的库的。基于学习的目的,最好自己写一个这样的库,所以,问题来了,怎么实现一个HTML parser?或者更简单的,怎么实现一个正则匹配?
如何管理一个请求的周期,因为一个请求的周期中,状态太多了。为什么状态多,因为一个请求会涉及很多异步操作,首先获取该用户的答案页面,这时候要等待server的回复,处理完以后获得改用户所有关注的人和关注者的页面,也要等待server的回复,再把这些所有用户加入队列后,这个请求周期才算结束。
需要自己处理一些HTTP header的细节。比如不希望接受到HTTP response header里Transfer Encoding: chuncked回复,因为它显然没有Content-length直接获取到数据长度来得方便,该怎么办?再比如不希望接受到gzip处理过的数据,希望收到plain text,又该怎么办?
架构怎么设计。首先最底层是TCP层,上层应该封装一个数据接收层,再上层应该是HTML解析层,最后是事件循环层。这些层次/模块怎么做到耦合度最低?
网络异常怎么处理,比如read返回error(eg Connection reset by peer),或者EOF。EOF需要重新建立一个新的连接,然后继续前一个请求(或者说继续状态机)。
用C++相比Python,NodeJS的优点
系统的掌控性。比如我们希望TCP连接数要控制在1000,完全可能很容易地实现。并且可以知道哪里会耗内存、CPU,底层在发生什么我们更容易知道。比如,在HTTP request header里写上Connection: keep-alive可以让很多请求复用一个TCP连接,在用C++实现的时候,对应的实现方法很简单粗暴:从socket读完对方服务器发来的response后,再构造一个header发过去即可。
因为一些内建库的缺乏,并且出发点是学习,我们会重新造一些轮子,与此同时,提高了编程能力。 比如说读配置文件,格式是json,可以自己用C写个json parser。再比如上文提到的HTML parser,也可以用C写一个,还有基于epoll的事件循环,可以抽象成一个通用的网络库。有太多轮子可以造,要把其中任意一个轮子写好都是非常难的事情。
高性能。可能由于网络的大延迟使得这个优点不那么明显。
总结
本文基于我一年多之前写的zhihu爬虫以及最近的大规模改进,总结了如何用C++编写的高效、基于事件驱动的知乎爬虫,同时也列出了用C++写爬虫时的一些难点与收获。
如果你有兴趣看看竟然有人用C++写了一个爬虫究竟是什么样子的,代码在这里。
. END.
看完本文请分享一下吧!让其他人也可以GET到新知识!

网站将用户资料分门别类的存储在百度中
网站优化 • 优采云 发表了文章 • 0 个评论 • 72 次浏览 • 2022-06-05 16:01
c爬虫抓取网页数据,可以得到我们想要的各种格式的数据用户信息是可以作为数据有价值的获取来源。比如一个网站将用户资料分门别类的存储在百度中,那么用户不仅可以接受百度的url信息,还可以查看百度收录了哪些对自己有用的用户信息。根据产品上线的数据质量对用户信息的价值进行确定,在这里对用户信息的价值分为初级价值、中级价值、高级价值三类(根据产品和相关业务流程的特征进行下划分),初级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看新推荐的商品、查看优惠券的使用情况中级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看优惠券的使用情况高级价值比如某宝同城生活服务平台的用户在微信上获取到完整图片视频等内容的用户信息通过以上的分类,一般可以根据产品的定位将用户信息划分出来,放到哪里去获取都可以。info_data_name。
根据业务特征选择,设计合理的信息模型和链路,及时对信息进行处理对网页中的信息进行解析,提取信息特征,并储存起来需要获取什么样的信息信息以数据库的形式存储即可,没有特定指标来要求储存速度,txt或者json,提取关键字,把抽象内容链接到一起即可,最重要的是全量的准确性,保证准确性的一点是有足够快的读写速度。
对于广告业务而言,定制特征是非常重要的,比如有的广告有固定的位置标识、pagerank、ctr特征等等,然后如果参与定制特征的平台多,定制特征的粒度够细的话,本地数据库的使用率会比较低对数据进行分类管理,类似etl,用一定的算法和策略将所有的存储到不同数据库中去如果需要进行分析,可以自己对业务、流程进行重构,比如:消息队列,过滤流程,负载均衡等等,将不同的业务特征,流程拆分成不同粒度的数据仓库。 查看全部
网站将用户资料分门别类的存储在百度中
c爬虫抓取网页数据,可以得到我们想要的各种格式的数据用户信息是可以作为数据有价值的获取来源。比如一个网站将用户资料分门别类的存储在百度中,那么用户不仅可以接受百度的url信息,还可以查看百度收录了哪些对自己有用的用户信息。根据产品上线的数据质量对用户信息的价值进行确定,在这里对用户信息的价值分为初级价值、中级价值、高级价值三类(根据产品和相关业务流程的特征进行下划分),初级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看新推荐的商品、查看优惠券的使用情况中级价值比如xxx宝马集团电子商务平台用户在购物车不只是购买自己想要的产品,还可以查看优惠券的使用情况高级价值比如某宝同城生活服务平台的用户在微信上获取到完整图片视频等内容的用户信息通过以上的分类,一般可以根据产品的定位将用户信息划分出来,放到哪里去获取都可以。info_data_name。
根据业务特征选择,设计合理的信息模型和链路,及时对信息进行处理对网页中的信息进行解析,提取信息特征,并储存起来需要获取什么样的信息信息以数据库的形式存储即可,没有特定指标来要求储存速度,txt或者json,提取关键字,把抽象内容链接到一起即可,最重要的是全量的准确性,保证准确性的一点是有足够快的读写速度。
对于广告业务而言,定制特征是非常重要的,比如有的广告有固定的位置标识、pagerank、ctr特征等等,然后如果参与定制特征的平台多,定制特征的粒度够细的话,本地数据库的使用率会比较低对数据进行分类管理,类似etl,用一定的算法和策略将所有的存储到不同数据库中去如果需要进行分析,可以自己对业务、流程进行重构,比如:消息队列,过滤流程,负载均衡等等,将不同的业务特征,流程拆分成不同粒度的数据仓库。
如何构建一个分布式爬虫:实战篇
网站优化 • 优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2022-06-05 05:09
种子博主具体信息
这里我们就看到了他的具体信息了。然后,我们看该页面的 url 构造
我直接 copy 的地址栏的 url。这样做有啥不好的呢?对于老鸟来说,一下就看出来了,这样做的话,可能会导致信息不全,因为可能有些信息是动态加载的。所以,我们需要通过抓包来判断到底微博会通过该 url 返回所有信息,还是需要请求一些 ajax 链接才会返回一些关键信息。这里我就重复一下我的观点:抓包很重要,抓包很重要,抓包很重要!重要的事情说三遍。关于抓包,我在模拟登陆微博和模拟登陆百度云都详细讲过了,这里我就不讲了。
我们抓完包,发现并没有 ajax 请求。那么可以肯定请求前面的 url,会返回所有信息。我们通过点击鼠标右键,查看网页源代码,然后ctrl a、ctrl c将所有的页面源码保存到本地,这里我命名为personinfo.html。我们用浏览器打开该文件,发现我们需要的所有信息都在这段源码中,这个工作和抓包判断数据是否全面有些重复,但是在我看来是必不可少的,因为我们解析页面数据的时候还可以用到这个 html 文件,如果我们每次都通过网络请求去解析内容的话,那么可能账号没一会儿就会被封了(因为频繁访问微博信息),所以我们需要把要解析的文件保存到本地。
从上面分析中我们可以得知
这个 url 就是获取用户数据的 url。那么我们在只知道用户 id 的时候怎么构造它呢?我们可以多拿几个用户 id 来做测试,看构造是否有规律,比如我这里以用户名为网易云音乐的用户做分析,发现它的用户信息页面构造如下
这个就和上面那个不同了。但是我们仔细观察,可以发现上面那个是个人用户,下面是企业微博用户。我们尝试一下把它们 url 格式都统一为第一种或者第二种的格式
这样会出现 404,那么统一成上面那种呢?
这样子的话,它会被重定向到用户主页,而不是用户详细资料页。所以也就不对了。那么该以什么依据判断何时用第一种 url 格式,何时用第二种 url 格式呢?我们多翻几个用户,会发现除了100505之外,还有100305、100206等前缀,那么我猜想这个应该可以区分不同用户。这个前缀在哪里可以得到呢?我们打开我们刚保存的页面源码,搜索100505,可以发现
domain
微博应该是根据这个来区分不同用户类型的。这里大家可以自己也可以试试,看不同用户的domain是否不同。为了数据能全面,我也是做了大量测试,发现个人用户的 domain 是1005051,作家是100305,其他基本都是认证的企业号。前两个个人信息的 url 构造就是
后者的是
弄清楚了个人信息 url 的构造方式,但是还有一个问题。我们已知只有 uid 啊,没有 domain 啊。如果是企业号,我们通过domain=100505会被重定向到主页,如果是作家等(domain=100305 或者 100306),也会被重定向主页。我们在主页把 domain 提取出来,再请求一次,不就能拿到用户详细信息了吗?
关于如何构造获取用户信息的 url 的相关分析就到这里了。因为我们是在登录的情况下进行数据抓取的,可能在抓取的时候,某个账号突然就被封了,或者由于网络原因,某次请求失败了,该如何处理?对于前者,我们需要判断每次请求返回的内容是否符合预期,也就是看 response url 是否正常,看 response content 是否是 404 或者让你验证手机号等,对于后者,我们可以做一个简单的重试策略,大概代码如下
<p>@timeout_decorator
def get_page(url, user_verify=True, need_login=True):
"""
:param url: 待抓取 url
:param user_verify: 是否为可能出现验证码的页面(ajax 连接不会出现验证码,如果是请求微博或者用户信息可能出现验证码),否为抓取转发的 ajax 连接
:param need_login: 抓取页面是否需要登录,这样做可以减小一些账号的压力
:return: 返回请求的数据,如果出现 404 或者 403,或者是别的异常,都返回空字符串
"""
crawler.info('本次抓取的 url 为{url}'.format(url=url))
count = 0<p> while count 查看全部
如何构建一个分布式爬虫:实战篇
种子博主具体信息
这里我们就看到了他的具体信息了。然后,我们看该页面的 url 构造
我直接 copy 的地址栏的 url。这样做有啥不好的呢?对于老鸟来说,一下就看出来了,这样做的话,可能会导致信息不全,因为可能有些信息是动态加载的。所以,我们需要通过抓包来判断到底微博会通过该 url 返回所有信息,还是需要请求一些 ajax 链接才会返回一些关键信息。这里我就重复一下我的观点:抓包很重要,抓包很重要,抓包很重要!重要的事情说三遍。关于抓包,我在模拟登陆微博和模拟登陆百度云都详细讲过了,这里我就不讲了。
我们抓完包,发现并没有 ajax 请求。那么可以肯定请求前面的 url,会返回所有信息。我们通过点击鼠标右键,查看网页源代码,然后ctrl a、ctrl c将所有的页面源码保存到本地,这里我命名为personinfo.html。我们用浏览器打开该文件,发现我们需要的所有信息都在这段源码中,这个工作和抓包判断数据是否全面有些重复,但是在我看来是必不可少的,因为我们解析页面数据的时候还可以用到这个 html 文件,如果我们每次都通过网络请求去解析内容的话,那么可能账号没一会儿就会被封了(因为频繁访问微博信息),所以我们需要把要解析的文件保存到本地。
从上面分析中我们可以得知
这个 url 就是获取用户数据的 url。那么我们在只知道用户 id 的时候怎么构造它呢?我们可以多拿几个用户 id 来做测试,看构造是否有规律,比如我这里以用户名为网易云音乐的用户做分析,发现它的用户信息页面构造如下
这个就和上面那个不同了。但是我们仔细观察,可以发现上面那个是个人用户,下面是企业微博用户。我们尝试一下把它们 url 格式都统一为第一种或者第二种的格式
这样会出现 404,那么统一成上面那种呢?
这样子的话,它会被重定向到用户主页,而不是用户详细资料页。所以也就不对了。那么该以什么依据判断何时用第一种 url 格式,何时用第二种 url 格式呢?我们多翻几个用户,会发现除了100505之外,还有100305、100206等前缀,那么我猜想这个应该可以区分不同用户。这个前缀在哪里可以得到呢?我们打开我们刚保存的页面源码,搜索100505,可以发现
domain
微博应该是根据这个来区分不同用户类型的。这里大家可以自己也可以试试,看不同用户的domain是否不同。为了数据能全面,我也是做了大量测试,发现个人用户的 domain 是1005051,作家是100305,其他基本都是认证的企业号。前两个个人信息的 url 构造就是
后者的是
弄清楚了个人信息 url 的构造方式,但是还有一个问题。我们已知只有 uid 啊,没有 domain 啊。如果是企业号,我们通过domain=100505会被重定向到主页,如果是作家等(domain=100305 或者 100306),也会被重定向主页。我们在主页把 domain 提取出来,再请求一次,不就能拿到用户详细信息了吗?
关于如何构造获取用户信息的 url 的相关分析就到这里了。因为我们是在登录的情况下进行数据抓取的,可能在抓取的时候,某个账号突然就被封了,或者由于网络原因,某次请求失败了,该如何处理?对于前者,我们需要判断每次请求返回的内容是否符合预期,也就是看 response url 是否正常,看 response content 是否是 404 或者让你验证手机号等,对于后者,我们可以做一个简单的重试策略,大概代码如下
<p>@timeout_decorator
def get_page(url, user_verify=True, need_login=True):
"""
:param url: 待抓取 url
:param user_verify: 是否为可能出现验证码的页面(ajax 连接不会出现验证码,如果是请求微博或者用户信息可能出现验证码),否为抓取转发的 ajax 连接
:param need_login: 抓取页面是否需要登录,这样做可以减小一些账号的压力
:return: 返回请求的数据,如果出现 404 或者 403,或者是别的异常,都返回空字符串
"""
crawler.info('本次抓取的 url 为{url}'.format(url=url))
count = 0<p> while count
微博各种数据抓取思路与难点总结——小白爬虫进阶(1)
网站优化 • 优采云 发表了文章 • 0 个评论 • 304 次浏览 • 2022-06-04 11:43
最近后台留言异常的多,还有不少催更,看来各位小伙伴都是寒假稍歇后就立刻又投身于秃头事业了,让大家久等了,2022一起继续加油。
在之前的小白爬虫实战(1)里,我们以马云的微博为例初步演示了如何爬取一个微博用户的所有微博文本(回顾戳这→),最近有很多同学后台问起详细的思路,也有小伙伴对如何进一步抓取微博转发、评论、点赞数据甚至配图的抓取方法提出了疑问。
针对以上问题,本篇对微博数据的抓取做一个专门的梳理与总结,本文分为以下三部分:
1、抓取URL的构造
2、微博文本、转发、评论、点赞数据的抓取与保存
3、微博图片的抓取与保存
经过这三部分的梳理,相信各位能对有关微博的抓取有更进一步的了解,无论是抓取话题还是抓取热搜,万变不离其宗,只需要按需求在本文基础上进行些改动即可。
注意:本篇是基于爬虫实战(1)等前面相关内容之上的总结,一些基础的内容便不再赘述,有需要的小伙伴可以回顾之前的相关内容:
下面我们开始这三部分——
1
抓取URL的构造
在爬虫实战(1)中,我们用检查中的XHR过滤器找到了获取数据所需的链接地址,这个链接地址有一大坨,第一页链接与之后链接的差距就在于第一页的链接尾部没有since_id参数,这次我们进一步对这一大坨链接进行分解分析。
%3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
上面即是马云微博数据的第二页链接,若是把链接末尾的since_id删去即为第一页链接。在这么一大坨链接里,最终是靠着末尾since_id的变化实现获取下一页数据的,在爬虫实战(1)中,我们是直接将这一大坨复制粘贴到代码中,而为since_id专门设了一个变量,这次我们再进一步将这个链接拆分看看。
实际上,这么一大坨连接中,只有
为基础连接,后面的一长串都是各种各样的参数组合,比如uid、t、luicode等等,而这一长串由百分号、数字和字母构成的部分我们可以通过解码得到它的实际文本
%3D1%26q%3D%E9%A9%AC%E4%BA%91
我们可以在中对上面这行奇奇怪怪的内容进行URL解码:
解码之后:
通过解码可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的实际文本含义为“=1&q=马云”,据此可得这一大串链接的真实表达为:
=1&q=马云&type=uid&value=2145291155&containerid=91155&since_id=44903
也就是一个基础链接加上各种必要参数的组合。在Python中我们可以通过调用urlencode()方法将构造的参数字典与基础连接组合生成完整链接,据此我们首先构造一个生成完整请求链接的函数:
from urllib.parse import urlencode
def generate_url(since_id='0'):
"""
构造完整链接 """
base_url = ''
params = {
'uid': '2145291155',
't': '0',
'luicode': '10000011',
'lfid': '100103type=1',
'q': '马云',
'type': 'uid',
'value': '2145291155',
'containerid': '91155',
'since_id': since_id
}
url = base_url + urlencode(params)
return url
generate_url
因为只有since_id是变化的,而第一页链接又不含since_id,所以这里设一个since_id默认值为0的变量。
到此,抓取所需的URL便构造完成了。
2
微博文本、转发、评论、点赞数据的抓取与保存
在爬虫实战(1)中说到,若用火狐浏览器访问我们所构造的URL,可以得到结构化的json数据,而我们所需要抓取的目标就在这些json数据之中。微博文本在mblog的text下,而转发、评论、点赞数据也异曲同工:
数据位置
数据含义
mblog→reposts_count
点赞数
mblog→comments_count 查看全部
微博各种数据抓取思路与难点总结——小白爬虫进阶(1)
最近后台留言异常的多,还有不少催更,看来各位小伙伴都是寒假稍歇后就立刻又投身于秃头事业了,让大家久等了,2022一起继续加油。
在之前的小白爬虫实战(1)里,我们以马云的微博为例初步演示了如何爬取一个微博用户的所有微博文本(回顾戳这→),最近有很多同学后台问起详细的思路,也有小伙伴对如何进一步抓取微博转发、评论、点赞数据甚至配图的抓取方法提出了疑问。
针对以上问题,本篇对微博数据的抓取做一个专门的梳理与总结,本文分为以下三部分:
1、抓取URL的构造
2、微博文本、转发、评论、点赞数据的抓取与保存
3、微博图片的抓取与保存
经过这三部分的梳理,相信各位能对有关微博的抓取有更进一步的了解,无论是抓取话题还是抓取热搜,万变不离其宗,只需要按需求在本文基础上进行些改动即可。
注意:本篇是基于爬虫实战(1)等前面相关内容之上的总结,一些基础的内容便不再赘述,有需要的小伙伴可以回顾之前的相关内容:
下面我们开始这三部分——
1
抓取URL的构造
在爬虫实战(1)中,我们用检查中的XHR过滤器找到了获取数据所需的链接地址,这个链接地址有一大坨,第一页链接与之后链接的差距就在于第一页的链接尾部没有since_id参数,这次我们进一步对这一大坨链接进行分解分析。
%3D1%26q%3D%E9%A9%AC%E4%BA%91&type=uid&value=2145291155&containerid=91155&since_id=44903
上面即是马云微博数据的第二页链接,若是把链接末尾的since_id删去即为第一页链接。在这么一大坨链接里,最终是靠着末尾since_id的变化实现获取下一页数据的,在爬虫实战(1)中,我们是直接将这一大坨复制粘贴到代码中,而为since_id专门设了一个变量,这次我们再进一步将这个链接拆分看看。
实际上,这么一大坨连接中,只有
为基础连接,后面的一长串都是各种各样的参数组合,比如uid、t、luicode等等,而这一长串由百分号、数字和字母构成的部分我们可以通过解码得到它的实际文本
%3D1%26q%3D%E9%A9%AC%E4%BA%91
我们可以在中对上面这行奇奇怪怪的内容进行URL解码:
解码之后:
通过解码可知,%3D1%26q%3D%E9%A9%AC%E4%BA%91的实际文本含义为“=1&q=马云”,据此可得这一大串链接的真实表达为:
=1&q=马云&type=uid&value=2145291155&containerid=91155&since_id=44903
也就是一个基础链接加上各种必要参数的组合。在Python中我们可以通过调用urlencode()方法将构造的参数字典与基础连接组合生成完整链接,据此我们首先构造一个生成完整请求链接的函数:
from urllib.parse import urlencode
def generate_url(since_id='0'):
"""
构造完整链接 """
base_url = ''
params = {
'uid': '2145291155',
't': '0',
'luicode': '10000011',
'lfid': '100103type=1',
'q': '马云',
'type': 'uid',
'value': '2145291155',
'containerid': '91155',
'since_id': since_id
}
url = base_url + urlencode(params)
return url
generate_url
因为只有since_id是变化的,而第一页链接又不含since_id,所以这里设一个since_id默认值为0的变量。
到此,抓取所需的URL便构造完成了。
2
微博文本、转发、评论、点赞数据的抓取与保存
在爬虫实战(1)中说到,若用火狐浏览器访问我们所构造的URL,可以得到结构化的json数据,而我们所需要抓取的目标就在这些json数据之中。微博文本在mblog的text下,而转发、评论、点赞数据也异曲同工:
数据位置
数据含义
mblog→reposts_count
点赞数
mblog→comments_count
Python爬虫入门,8个常用爬虫技巧盘点
网站优化 • 优采云 发表了文章 • 0 个评论 • 136 次浏览 • 2022-06-04 06:47
5、页面解析
对于页面解析最强大的当然是正则表达式,
这个对于不同网站不同的使用者都不一样,就不用过多的说明。
其次就是解析库了,常用的有两个lxml和BeautifulSoup。
对于这两个库,我的评价是,
都是HTML/XML的处理库,Beautifulsoup纯python实现,效率低,
但是功能实用,比如能用通过结果搜索获得某个HTML节点的源码;
lxmlC语言编码,高效,支持Xpath。
6.验证码的处理
碰到验证码咋办?
这里分两种情况处理:
google那种验证码,没办法。
简单的验证码:字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,
这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,
然后划分单个字符,划分好了以后再通过特征提取的方法(例如PCA)降维并生成特征库,
然后把验证码和特征库进行比较。
这个比较复杂,这里就不展开了,
具体做法请弄本相关教科书好好研究一下。
7. gzip/deflate支持
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,
以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。
这就意味着抓取速度会快5倍。
然而python的urllib/urllib2默认都不支持压缩
要返回压缩格式,必须在request的header里面写明’accept-encoding’,
然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。
如何让urllib2自动支持gzip, defalte呢?
其实可以继承BaseHanlder类,
然后build_opener的方式来处理:
8、多线程并发抓取
单线程太慢的话,就需要多线程了,
这里给个简单的线程池模板 这个程序只是简单地打印了1-10,
但是可以看出是并发的。
虽然说Python的多线程很鸡肋
但是对于爬虫这种网络频繁型,
还是能一定程度提高效率的。
9. 总结
阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身。
Python虽然是基于C语言编写,但是摒弃了C中复杂的指针,使其变得简明易学。
并且作为开源软件,Python允许对代码进行阅读,拷贝甚至改进。
这些性能成就了Python的高效率,有“人生苦短,我用Python”之说,是一种十分精彩又强大的语言。
总而言之,开始学Python一定要注意这4点:
1.代码规范,这本身就是一个非常好的习惯,如果开始不养好好的代码规划,以后会很痛苦。
2.多动手,少看书,很多人学Python就一味的看书,这不是学数学物理,你看例题可能就会了,学习Python主要是学习编程思想。
3.勤练习,学完新的知识点,一定要记得如何去应用,不然学完就会忘,学我们这行主要都是实际操作。
4.学习要有效率,如果自己都觉得效率非常低,那就停不停,找一下原因,去问问过来人这是为什么。
推荐↓↓↓
长
按
关
注
【】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。 查看全部
Python爬虫入门,8个常用爬虫技巧盘点
5、页面解析
对于页面解析最强大的当然是正则表达式,
这个对于不同网站不同的使用者都不一样,就不用过多的说明。
其次就是解析库了,常用的有两个lxml和BeautifulSoup。
对于这两个库,我的评价是,
都是HTML/XML的处理库,Beautifulsoup纯python实现,效率低,
但是功能实用,比如能用通过结果搜索获得某个HTML节点的源码;
lxmlC语言编码,高效,支持Xpath。
6.验证码的处理
碰到验证码咋办?
这里分两种情况处理:
google那种验证码,没办法。
简单的验证码:字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,
这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,
然后划分单个字符,划分好了以后再通过特征提取的方法(例如PCA)降维并生成特征库,
然后把验证码和特征库进行比较。
这个比较复杂,这里就不展开了,
具体做法请弄本相关教科书好好研究一下。
7. gzip/deflate支持
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,
以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。
这就意味着抓取速度会快5倍。
然而python的urllib/urllib2默认都不支持压缩
要返回压缩格式,必须在request的header里面写明’accept-encoding’,
然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。
如何让urllib2自动支持gzip, defalte呢?
其实可以继承BaseHanlder类,
然后build_opener的方式来处理:
8、多线程并发抓取
单线程太慢的话,就需要多线程了,
这里给个简单的线程池模板 这个程序只是简单地打印了1-10,
但是可以看出是并发的。
虽然说Python的多线程很鸡肋
但是对于爬虫这种网络频繁型,
还是能一定程度提高效率的。
9. 总结
阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身。
Python虽然是基于C语言编写,但是摒弃了C中复杂的指针,使其变得简明易学。
并且作为开源软件,Python允许对代码进行阅读,拷贝甚至改进。
这些性能成就了Python的高效率,有“人生苦短,我用Python”之说,是一种十分精彩又强大的语言。
总而言之,开始学Python一定要注意这4点:
1.代码规范,这本身就是一个非常好的习惯,如果开始不养好好的代码规划,以后会很痛苦。
2.多动手,少看书,很多人学Python就一味的看书,这不是学数学物理,你看例题可能就会了,学习Python主要是学习编程思想。
3.勤练习,学完新的知识点,一定要记得如何去应用,不然学完就会忘,学我们这行主要都是实际操作。
4.学习要有效率,如果自己都觉得效率非常低,那就停不停,找一下原因,去问问过来人这是为什么。
推荐↓↓↓
长
按
关
注
【】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。
实战演练——爱婴医院中莆田系医院数据分析(一)
网站优化 • 优采云 发表了文章 • 0 个评论 • 67 次浏览 • 2022-06-04 06:44
技术总编:张 邯
爬虫俱乐部将于2020年1月5日至11日在湖北武汉举行为期一周的Stata编程技术定制培训,此次采取初级班和高级班分批次培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata软件编程、金融计量知识和实证分析方法,使大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。目前正在火热招生中~详细培训大纲及报名方式,请点击《》或点击文末阅读原文呦~
自2015年党的十八届五中全会开放二孩政策实施以来,越来越多天真可爱的孩子在这个中国特色社会新时代呱呱坠地。但是,“7岁男童坠楼身亡”、“幼儿园虐童”等新闻时时刻刻提醒我们,要全方位、多角度对这些祖国未来的建设者进行保护。当然,保护他们要从保护他们的出生做起。
开放二孩政策实施后,国家妇幼健康司响应号召,在2015年11月公布了《国家卫生计生委关于公布全国爱婴医院名单的公告》,旨在“不断改善产科儿科服务质量,逐步提高母乳喂养率,降低非医学指征剖宫产率,保障调整完善生育政策顺利实施”。(网址:)
当小编打开这些名单浏览的时候,这里面有些医院的名字竟形同“莆田系医院”,为了识别这其中为数不多的“莆田系医院”,小编决定使用Python来一探究竟。
由于篇幅限制,本篇重点介绍如何获取所需的.docx文件,下篇重点介绍如何提取.docx文件中的表格信息并与已有的数据库进行匹配。
本文涉及的技术要点:
①获取公告附件②获取word文件中的表格信息③ 将.doc文件转换为.docx文件
一、使用网络爬虫技术抓取爱婴医院名单
1、创建文件夹并改变缺省路径
导入Python的os标准库,判断是否存在我们需要的文件夹,如果不存在则创建,将新创建的文件夹作为缺省路径,程序如下:
import osif not os.path.exists(r"D:/爱婴医院"): os.mkdir(r"D:/爱婴医院")os.chdir(r"D:/爱婴医院")
2、导入requests标准库和re标准库抓取WORD文件
requests和re库的使用在爬虫俱乐部往期推文《》和《》中已详细介绍。首先,导入标准库,构造headers,并抓取网页源代码,程序如下:
import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字节码再转换为字符串,避免乱码。print(text)
结果如下:
可见,我们使用requests库成功将网页源代码抓取下来。源代码中存有WORD文件的URL,我们将其中一个复制下来进行分析:
<A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市爱婴医院名单.doc</A></P>
其中的URL可以使用正则表达式A[ ]target.*?href="(.*?)"进行提取,我们提取出32个WORD文件的URL并放在一个列表中,程序如下:
urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
结果如下:
最后,使用requests库,根据列表中的URL下载WORD文件,程序如下:
for nu,c in enumerate(c_url): co = requests.get(c) #获取文件 suffix = os.path.splitext(c)[1] #分离文件名与文件后缀(.doc或.docx) filename = str(nu)+suffix #用序号给文件命名,生成新的文件名 with open(filename,'wb') as f: f.write(co.content)
此时,在缺省路径中就出现了我们需要的WORD文件,结果如下:
二、将.doc文件转换为.docx文件
由于Python无法读取.doc文件,因此我们先将.doc转换为.docx。
导入标准库并定义转化函数:
from win32com import client# win32com.client可以直接调用VBA的库,对Word、Excel进行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打开word。 doc = word.Documents.Open(path) # 打开目标路径下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close() word.Quit() #退出
上述函数需要传入文件名。接下来定义一个函数,用来将指定文件夹中的所有文件存入历列表中:
def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路径, 将多个路径组合后返回 if os.path.isdir(i): #用于判断某一对象是否为目录 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i) return file_list
调用上述函数进行转换并删掉.doc文件,程序如下:
dir_path = "D:\爱婴医院" #批量转换文件夹ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#删掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc": os.remove(c)
结果如下:
此时,文件就全部转换为了.docx文件。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。投稿邮箱:投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。
查看全部
实战演练——爱婴医院中莆田系医院数据分析(一)
技术总编:张 邯
爬虫俱乐部将于2020年1月5日至11日在湖北武汉举行为期一周的Stata编程技术定制培训,此次采取初级班和高级班分批次培训。课程通过案例教学模式,旨在帮助大家在短期内掌握Stata软件编程、金融计量知识和实证分析方法,使大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。目前正在火热招生中~详细培训大纲及报名方式,请点击《》或点击文末阅读原文呦~
自2015年党的十八届五中全会开放二孩政策实施以来,越来越多天真可爱的孩子在这个中国特色社会新时代呱呱坠地。但是,“7岁男童坠楼身亡”、“幼儿园虐童”等新闻时时刻刻提醒我们,要全方位、多角度对这些祖国未来的建设者进行保护。当然,保护他们要从保护他们的出生做起。
开放二孩政策实施后,国家妇幼健康司响应号召,在2015年11月公布了《国家卫生计生委关于公布全国爱婴医院名单的公告》,旨在“不断改善产科儿科服务质量,逐步提高母乳喂养率,降低非医学指征剖宫产率,保障调整完善生育政策顺利实施”。(网址:)
当小编打开这些名单浏览的时候,这里面有些医院的名字竟形同“莆田系医院”,为了识别这其中为数不多的“莆田系医院”,小编决定使用Python来一探究竟。
由于篇幅限制,本篇重点介绍如何获取所需的.docx文件,下篇重点介绍如何提取.docx文件中的表格信息并与已有的数据库进行匹配。
本文涉及的技术要点:
①获取公告附件②获取word文件中的表格信息③ 将.doc文件转换为.docx文件
一、使用网络爬虫技术抓取爱婴医院名单
1、创建文件夹并改变缺省路径
导入Python的os标准库,判断是否存在我们需要的文件夹,如果不存在则创建,将新创建的文件夹作为缺省路径,程序如下:
import osif not os.path.exists(r"D:/爱婴医院"): os.mkdir(r"D:/爱婴医院")os.chdir(r"D:/爱婴医院")
2、导入requests标准库和re标准库抓取WORD文件
requests和re库的使用在爬虫俱乐部往期推文《》和《》中已详细介绍。首先,导入标准库,构造headers,并抓取网页源代码,程序如下:
import requestsimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'Host': 'www.nhc.gov.cn', 'Referer': 'http://www.nhc.gov.cn/fys/s7906/201511/e5650712dbcd449e9d2e01129a698b9c.shtml', 'Cookie': 'FSSBBIl1UgzbN7N80S=IIRSdCvBkEfkV.B2JY9RYhaETIf1BuxVpvEkSoPAJNFoG0jDMD0Ful2W19MSwjQT; yfx_c_g_u_id_10006654=_ck19080819145412635280045357765; _gscu_2059686908=65262894vmq4k445; yfx_f_l_v_t_10006654=f_t_1565262894262__r_t_1566175543011__v_t_1566175543011__r_c_2; _gscbrs_2059686908=1; yfx_mr_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_mr_f_10006654=%3A%3Amarket_type_free_search%3A%3A%3A%3Abaidu%3A%3A%3A%3A%3A%3A%3A%3Awww.baidu.com%3A%3A%3A%3Apmf_from_free_search; yfx_key_10006654=; security_session_verify=27b11d4bf074ab3d320a0abb616f351f; banggoo.nuva.cookie=1|XVn2H|XVnyw; FSSBBIl1UgzbN7N80T=3r.zHapFkhZJ9axZJ1O.c4IFBETpXD7V97EmMfYcNch3_sxH_Btj9.wKGGKtWVFD4JTZMrYQH4I_cyZS.TVLlnmOlnWWQYX1KSl_0JUVaqTV5NSoiWZ2yDjJtV0RKxM3mtcPiY3b6wUjzJcPd4Z3u2ns76vO.lskE3joV_Gsk37Wj7hd7a.qnhOQazlKQrIZW8zGEH.8cPkVTO626ptQpnK35KuJcjrdVKTUEIq7bS81Ba.CKHUaDxNyxwsVMVkUiIGOGGD9sL3MFcik_S05TQa174cT51WxsHLZ_d4FFWBq3LZzaqvAM.ybpZ0vwVcPApVOILVksCY4w7adafW4.rYWCq_.1437bDWfT7f6FtSnb9G' }html = requests.get("http://www.nhc.gov.cn/fys/s790 ... 6quot;)text = html.content.decode('utf-8')#先抓取字节码再转换为字符串,避免乱码。print(text)
结果如下:
可见,我们使用requests库成功将网页源代码抓取下来。源代码中存有WORD文件的URL,我们将其中一个复制下来进行分析:
<A target=_blankhref="/ewebeditor/uploadfile/2015/11/20151117160507435.doc">1.北京市爱婴医院名单.doc</A></P>
其中的URL可以使用正则表达式A[ ]target.*?href="(.*?)"进行提取,我们提取出32个WORD文件的URL并放在一个列表中,程序如下:
urls = re.findall('A[ ]target.*?href="(.*?)"', text, re.S)print(urls)c_url = []for url in urls: ur = "http://www.nhc.gov.cn" + url c_url.append(ur)print(c_url)
结果如下:
最后,使用requests库,根据列表中的URL下载WORD文件,程序如下:
for nu,c in enumerate(c_url): co = requests.get(c) #获取文件 suffix = os.path.splitext(c)[1] #分离文件名与文件后缀(.doc或.docx) filename = str(nu)+suffix #用序号给文件命名,生成新的文件名 with open(filename,'wb') as f: f.write(co.content)
此时,在缺省路径中就出现了我们需要的WORD文件,结果如下:
二、将.doc文件转换为.docx文件
由于Python无法读取.doc文件,因此我们先将.doc转换为.docx。
导入标准库并定义转化函数:
from win32com import client# win32com.client可以直接调用VBA的库,对Word、Excel进行操作def doc_to_docx(path): if os.path.splitext(path)[1] == ".doc": word = client.Dispatch('Word.Application') #打开word。 doc = word.Documents.Open(path) # 打开目标路径下的文件 doc.SaveAs(os.path.splitext(path)[0]+".docx", 16) doc.Close() word.Quit() #退出
上述函数需要传入文件名。接下来定义一个函数,用来将指定文件夹中的所有文件存入历列表中:
def find_file(path, ext, file_list=[]): dir = os.listdir(path) for i in dir: i = os.path.join(path, i) #拼接文件路径, 将多个路径组合后返回 if os.path.isdir(i): #用于判断某一对象是否为目录 find_file(i, ext, file_list) else: if ext == os.path.splitext(i)[1]: file_list.append(i) return file_list
调用上述函数进行转换并删掉.doc文件,程序如下:
dir_path = "D:\爱婴医院" #批量转换文件夹ext = ".doc"file_list = find_file(dir_path, ext)for file in file_list: doc_to_docx(file)#删掉.doc文件files = os.listdir()print(files)for c in files: if os.path.splitext(c)[1] == ".doc": os.remove(c)
结果如下:
此时,文件就全部转换为了.docx文件。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。投稿邮箱:投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。
小白学 Python 爬虫(42):春节去哪里玩(系列终篇)
网站优化 • 优采云 发表了文章 • 0 个评论 • 186 次浏览 • 2022-05-26 12:39
人生苦短,我用 Python
前文传送门:
引言
首先恭喜看到这篇文章的同学,本篇内容为 「小白学 Python 爬虫」 系列的最后一篇。
看了下上面的前文传送门,加上这篇内容,总共有 42 篇,小编还是成就感满满,小编翻看了下公众号,第一篇文章是在 2019 年的 11 月 17 日推送的,大致数了数,将近两个月的时间。
当然,其中一些文章的质量并不高,很多都是在比较有限的时间中赶工赶出来的,还是感谢各位读者对小编的不离不弃,写的这么烂还没取关的绝对是真爱了。
正好下周就要过年了,从推送的时间算的话还有 10 个自然日左右的时间,可能很多同学可能过年是要出去玩的,那么去哪里玩就成了一个问题。
那么,怎么挑选去哪里玩最快的,小编想了想,直接去抓某站的数据吧,抓下来自己根据自己的情况查询下就好了。
那么今天的目标站是:马蜂窝。
这里小编还想说一点,虽然我们在前面 7、 8 篇文章中都是在讲如何使用爬虫框架 Scrapy ,说实话,小编并不觉得 Scrapy 有多方便,在一些简单的应用场景下,使用 Requests 库可能是最方便的选择, Scrapy 小编个人感觉还是更适合使用在一些中大型的爬虫项目中,简单的爬虫脚本使用最简单的技术栈就 ok 了,所以小编在本文中使用的技术栈还是 Requests + PyQuery 。
不要问为啥,问就是喜欢。
分析
首先我们访问链接,打开我们将要抓取的站点:。
这里是攻略的列表页,我们的目标是抓取来自游记的数据,其余的数据放过,原因是在游记中我们才能获取到一些具体的我们需要的数据。
数据的来源搞清楚了,接下来是翻页功能,只有清楚了如何翻页,我们才能源源不断的获取数据,否则就只能抓取第一页的数据了。
当把页面翻到最下面的时候就尴尬了,发现是自动加载更多,这个当然难不倒帅气逼人的小编我,掏出大杀器, Chrome 的开发者工具 F12 ,选到 network 标签页,再往下滚动一下,我们查看下这个页面发出的请求。
这个请求很有意思,请求的路径和我们访问的页面路径一样,但是请求类型变成 POST ,并且增加了请求参数,类型还是 Form 表单格式的。
截止这里,我们已经清楚了目标站点的数据路径以及翻页方式,虽然目前我们并不知道最大页数是多少,但是我们可以人为的设置一个最大页数,比如 100 或者 200 ,小编相信,这么大的站点上,几百页的游记应该是还有的。
代码
代码小编就直接贴出来,之前有同学希望数据是保存在 Excel 中的,本次实战的数据就不存数据库了,直接写入 Excel 。
import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 获取列表页面数据<br /> :param maxNum: 最大抓取页数<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游记':<br /> # 如果是游记,则进入内页数据抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 获取内页数据<br /> :param url: 内页链接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 获取数据采集区<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 数据格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 数据写入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格写入数据成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
因为马蜂窝在游记的详情页面上有反爬的限制,小编这里为了简单,直接从浏览器中将 cookie copy 出来,加在了请求头上。
小编这里简单的爬取了 5 个列表页的信息,如下:
好像数据量并不是很多的样子,各位同学可以尝试爬取 50 页或者 100 页的数据,这样得到的结果会有比较不错的参考价值。
好了,本篇内容到这里就结束了,小编随后会将全部的文章索引整理出来推在公众号上,方便大家查阅。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
示例代码-Github:
示例代码-Gitee:
查看全部
小白学 Python 爬虫(42):春节去哪里玩(系列终篇)
人生苦短,我用 Python
前文传送门:
引言
首先恭喜看到这篇文章的同学,本篇内容为 「小白学 Python 爬虫」 系列的最后一篇。
看了下上面的前文传送门,加上这篇内容,总共有 42 篇,小编还是成就感满满,小编翻看了下公众号,第一篇文章是在 2019 年的 11 月 17 日推送的,大致数了数,将近两个月的时间。
当然,其中一些文章的质量并不高,很多都是在比较有限的时间中赶工赶出来的,还是感谢各位读者对小编的不离不弃,写的这么烂还没取关的绝对是真爱了。
正好下周就要过年了,从推送的时间算的话还有 10 个自然日左右的时间,可能很多同学可能过年是要出去玩的,那么去哪里玩就成了一个问题。
那么,怎么挑选去哪里玩最快的,小编想了想,直接去抓某站的数据吧,抓下来自己根据自己的情况查询下就好了。
那么今天的目标站是:马蜂窝。
这里小编还想说一点,虽然我们在前面 7、 8 篇文章中都是在讲如何使用爬虫框架 Scrapy ,说实话,小编并不觉得 Scrapy 有多方便,在一些简单的应用场景下,使用 Requests 库可能是最方便的选择, Scrapy 小编个人感觉还是更适合使用在一些中大型的爬虫项目中,简单的爬虫脚本使用最简单的技术栈就 ok 了,所以小编在本文中使用的技术栈还是 Requests + PyQuery 。
不要问为啥,问就是喜欢。
分析
首先我们访问链接,打开我们将要抓取的站点:。
这里是攻略的列表页,我们的目标是抓取来自游记的数据,其余的数据放过,原因是在游记中我们才能获取到一些具体的我们需要的数据。
数据的来源搞清楚了,接下来是翻页功能,只有清楚了如何翻页,我们才能源源不断的获取数据,否则就只能抓取第一页的数据了。
当把页面翻到最下面的时候就尴尬了,发现是自动加载更多,这个当然难不倒帅气逼人的小编我,掏出大杀器, Chrome 的开发者工具 F12 ,选到 network 标签页,再往下滚动一下,我们查看下这个页面发出的请求。
这个请求很有意思,请求的路径和我们访问的页面路径一样,但是请求类型变成 POST ,并且增加了请求参数,类型还是 Form 表单格式的。
截止这里,我们已经清楚了目标站点的数据路径以及翻页方式,虽然目前我们并不知道最大页数是多少,但是我们可以人为的设置一个最大页数,比如 100 或者 200 ,小编相信,这么大的站点上,几百页的游记应该是还有的。
代码
代码小编就直接贴出来,之前有同学希望数据是保存在 Excel 中的,本次实战的数据就不存数据库了,直接写入 Excel 。
import requests<br />from pyquery import PyQuery<br />import xlsxwriter<br /><br />headers = {<br /> 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',<br /> 'cookie': '__jsluid_s=6fc5b4a3b5235afbfdafff4bbf7e6dbd; PHPSESSID=v9hm8hc3s56ogrn8si12fejdm3; mfw_uuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; _r=baidu; _rp=a%3A2%3A%7Bs%3A1%3A%22p%22%3Bs%3A18%3A%22www.baidu.com%2Flink%22%3Bs%3A1%3A%22t%22%3Bi%3A1579006045%3B%7D; oad_n=a%3A5%3A%7Bs%3A5%3A%22refer%22%3Bs%3A21%3A%22https%3A%2F%2Fwww.baidu.com%22%3Bs%3A2%3A%22hp%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A3%3A%22oid%22%3Bi%3A1026%3Bs%3A2%3A%22dm%22%3Bs%3A15%3A%22www.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222020-01-14+20%3A47%3A25%22%3B%7D; __mfwothchid=referrer%7Cwww.baidu.com; __omc_chl=; __mfwc=referrer%7Cwww.baidu.com; Hm_lvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579006048; uva=s%3A264%3A%22a%3A4%3A%7Bs%3A13%3A%22host_pre_time%22%3Bs%3A10%3A%222020-01-14%22%3Bs%3A2%3A%22lt%22%3Bi%3A1579006046%3Bs%3A10%3A%22last_refer%22%3Bs%3A137%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuR5Oj9n_xm4TSj7_1drQ1HRnFTYNM0M2TCljkjVrdIiUE-B2qPgh0MifEkceLE_U%26wd%3D%26eqid%3D93c920a80002dc72000000035e1db85c%22%3Bs%3A5%3A%22rhost%22%3Bs%3A13%3A%22www.baidu.com%22%3B%7D%22%3B; __mfwurd=a%3A3%3A%7Bs%3A6%3A%22f_time%22%3Bi%3A1579006046%3Bs%3A9%3A%22f_rdomain%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A6%3A%22f_host%22%3Bs%3A3%3A%22www%22%3B%7D; __mfwuuid=5e1db855-ab4a-da12-309c-afb9cf90d3dd; UM_distinctid=16fa418373e40f-070db24dfac29d-c383f64-1fa400-16fa418373fe31; __jsluid_h=b3f11fd3c79469af5c49be9ecb7f7b86; __omc_r=; __mfwa=1579006047379.58159.3.1579011903001.1579015057723; __mfwlv=1579015057; __mfwvn=2; CNZZDATA30065558=cnzz_eid%3D448020855-1579003717-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1579014923; bottom_ad_status=0; __mfwb=5e663dbc8869.7.direct; __mfwlt=1579019025; Hm_lpvt_8288b2ed37e5bc9b4c9f7008798d2de0=1579019026; __jsl_clearance=1579019146.235|0|fpZQ1rm7BHtgd6GdjVUIX8FJJ9o%3D'<br />}<br /><br /><br />s = requests.Session()<br /><br /><br />value = []<br /><br />defgetList(maxNum):<br /> """<br /> 获取列表页面数据<br /> :param maxNum: 最大抓取页数<br /> :return:<br /> """<br /> url = 'http://www.mafengwo.cn/gonglve/'<br /> s.get(url, headers = headers)<br /> for page in range(1, maxNum + 1):<br /> data = {'page': page}<br /> response = s.post(url, data = data, headers = headers)<br /> doc = PyQuery(response.text)<br /> items = doc('.feed-item').items()<br /> for item in items:<br /> if item('.type strong').text() == '游记':<br /> # 如果是游记,则进入内页数据抓取<br /> inner_url = item('a').attr('href')<br /> getInfo(inner_url)<br /><br /><br />defgetInfo(url):<br /> """<br /> 获取内页数据<br /> :param url: 内页链接<br /> :return:<br /> """<br /> response = s.get(url, headers = headers)<br /> doc = PyQuery(response.text)<br /> title = doc('title').text()<br /> # 获取数据采集区<br /> item = doc('.tarvel_dir_list')<br /> if len(item) == 0:<br /> return<br /> time = item('.time').text()<br /> day = item('.day').text()<br /> people = item('.people').text()<br /> cost = item('.cost').text()<br /> # 数据格式化<br /> if time == '':<br /> pass<br /> else:<br /> time = time.split('/')[1] if len(time.split('/')) > 1 else ''<br /><br /> if day == '':<br /> pass<br /> else:<br /> day = day.split('/')[1] if len(day.split('/')) > 1 else ''<br /><br /> if people == '':<br /> pass<br /> else:<br /> people = people.split('/')[1] if len(people.split('/')) > 1 else ''<br /><br /> if cost == '':<br /> pass<br /> else:<br /> cost = cost.split('/')[1] if len(cost.split('/')) > 1 else ''<br /><br /><br /> value.append([title, time, day, people, cost, url])<br /><br /><br />defwrite_excel_xlsx(value):<br /> """<br /> 数据写入Excel<br /> :param value:<br /> :return:<br /> """<br /> index = len(value)<br /><br /> workbook = xlsxwriter.Workbook('mfw.xlsx')<br /> sheet = workbook.add_worksheet()<br /> for i in range(1, index + 1):<br /> row = 'A' + str(i)<br /> sheet.write_row(row, value[i - 1])<br /> workbook.close()<br /> print("xlsx格式表格写入数据成功!")<br /><br /><br />defmain():<br /> getList(5)<br /> write_excel_xlsx(value)<br /><br />if __name__ == '__main__':<br /> main()<br />
因为马蜂窝在游记的详情页面上有反爬的限制,小编这里为了简单,直接从浏览器中将 cookie copy 出来,加在了请求头上。
小编这里简单的爬取了 5 个列表页的信息,如下:
好像数据量并不是很多的样子,各位同学可以尝试爬取 50 页或者 100 页的数据,这样得到的结果会有比较不错的参考价值。
好了,本篇内容到这里就结束了,小编随后会将全部的文章索引整理出来推在公众号上,方便大家查阅。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
示例代码-Github:
示例代码-Gitee:
一文搞懂爬虫Scrapy框架详解
网站优化 • 优采云 发表了文章 • 0 个评论 • 56 次浏览 • 2022-05-21 05:55
“Python爬虫Scrapy框架实践。”
大数据已经渗透到当今每一个行业和业务职能领域,成为重要的生产因素。”人们对于海量数据的挖掘和运用越来越密切,预示着爬虫工作者已经成为互联网数据公司的关键性职位,他们不但要精通数据抓取和分析,还要掌握搜索引擎和相关检索的算法,对内存、性能、分布式算法都要有一定的了解,并针对工作进程编排合理的布局。依据数据来预测某一种事物未来的发展趋势,以及对应的风险,提早解决未来即将遇到的风险,防范于未然。
一 Scrapy框架简介
Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
了解scrapy爬虫原理:Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构如下:
总结-scrapy大概流程如下:
Scrapy Engine:Scrapy引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。
Scheduler:调度器。从Scrapy Engine接受请求(requests)并排序列入队列,并在引擎再次请求时返回。用它来决定下一个抓取的网址是什么,同时去除重复的网址。
Downloader:下载器。抓取网页并将网页内容返还给Spiders。建立在twisted异步模型。
Spiders:爬虫。用户自定义的类,主要用来解析网页,提取Items,发送url跟进等新请求等。
Item Pipelines:管道。主要用来处理Spider解析出来的Items,进行按规则过滤,验证,持久化存储(如数据库存储)等
Downloader Middlewares:下载中间件。位于Scrapy Engine和Downloader之间,主要是处理Scrapy引擎与下载器之间的请求及响应。
Spider Middlewares:爬虫中间件。位于Scrapy Engine和Spiders之间,主要工作是处理Spiders的响应输入和请求输出。
Scheduler Middlewares:调度中间件。位于Scrapy Engine和Scheduler之间。主要工作是处理从Scrapy Engine发送到Scheduler的请求和响应。
二 Scrapy框架详解Scrapy由Python语言编写,是一个快速、高层次的屏幕抓取和Web抓取框架。1. 数据流向Scrapy数据流是由执行流程的核心引擎来控制的,流程如图所示。
框架组件数据流
1.ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
2.ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
3.ScrapyEngine向调度器请求下一个要爬取的url;
4.Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
5.页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
6.ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
7.Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
8.ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。
2Scrapy 的运作流程
制作 Scrapy 爬虫 一共需要 4 步:
1 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
2 明确目标 (编写 items.py):明确你想要抓取的目标,想要爬什么信息
3 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
4 存储内容 (pipelines.py):设计管道存储爬取内容
具体流程
1、scrapy安装
pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
检查是否安装成功:
scrapy versionScrapy 2.5.0
scrapy常用命令使用:
Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
2、创建项目
//创建一个测试项目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
3、第一个爬虫项目
注释:
scrapy genspider -l 查看当前可以使用的爬虫模板
scrapy genspider -t 创建爬虫文件
1.scrapy startproject scrapyproject2.在工程目录下创建爬虫baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默认)、crawl、csvfeed、xmlfeed这里name是爬虫的名字;domain是设置allowed_domains以及start_urls,这两个属性可以在爬虫类中修改<br /><br />cd scrapyprojectscrapy genspider baidu baidu.com (baidu 为爬虫的名称,baidu.com为要爬取的网站的域名)<br />输出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打开第一步创建的项目
目录及文件结构:
文件说明:
scrapy.cfg 项目的配置信息,主要为Scrapy命令行工具提供一个基础的配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py 设置数据存储模板,用于结构化数据,如:Django的Model
pipelines 数据处理行为,如:一般结构化的数据持久化
settings.py 配置文件,如:递归的层数、并发数,延迟下载等
spiders 爬虫目录,如:创建文件,编写爬虫规则
注意:一般创建爬虫文件时,以网站域名命名。
4. cd 项目目录,重写parse函数,然后启动爬虫,命令:
注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
scrapy crawl baidu
生成爬取结果
打开是界面:
05Scrapy校花网爬取实践
以校花网为例进行爬取,校花网:
创建xiaohuar spider:
scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
准备: 查看全部
一文搞懂爬虫Scrapy框架详解
“Python爬虫Scrapy框架实践。”
大数据已经渗透到当今每一个行业和业务职能领域,成为重要的生产因素。”人们对于海量数据的挖掘和运用越来越密切,预示着爬虫工作者已经成为互联网数据公司的关键性职位,他们不但要精通数据抓取和分析,还要掌握搜索引擎和相关检索的算法,对内存、性能、分布式算法都要有一定的了解,并针对工作进程编排合理的布局。依据数据来预测某一种事物未来的发展趋势,以及对应的风险,提早解决未来即将遇到的风险,防范于未然。
一 Scrapy框架简介
Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
了解scrapy爬虫原理:Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构如下:
总结-scrapy大概流程如下:
Scrapy Engine:Scrapy引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。
Scheduler:调度器。从Scrapy Engine接受请求(requests)并排序列入队列,并在引擎再次请求时返回。用它来决定下一个抓取的网址是什么,同时去除重复的网址。
Downloader:下载器。抓取网页并将网页内容返还给Spiders。建立在twisted异步模型。
Spiders:爬虫。用户自定义的类,主要用来解析网页,提取Items,发送url跟进等新请求等。
Item Pipelines:管道。主要用来处理Spider解析出来的Items,进行按规则过滤,验证,持久化存储(如数据库存储)等
Downloader Middlewares:下载中间件。位于Scrapy Engine和Downloader之间,主要是处理Scrapy引擎与下载器之间的请求及响应。
Spider Middlewares:爬虫中间件。位于Scrapy Engine和Spiders之间,主要工作是处理Spiders的响应输入和请求输出。
Scheduler Middlewares:调度中间件。位于Scrapy Engine和Scheduler之间。主要工作是处理从Scrapy Engine发送到Scheduler的请求和响应。
二 Scrapy框架详解Scrapy由Python语言编写,是一个快速、高层次的屏幕抓取和Web抓取框架。1. 数据流向Scrapy数据流是由执行流程的核心引擎来控制的,流程如图所示。
框架组件数据流
1.ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
2.ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
3.ScrapyEngine向调度器请求下一个要爬取的url;
4.Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
5.页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
6.ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
7.Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
8.ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。
2Scrapy 的运作流程
制作 Scrapy 爬虫 一共需要 4 步:
1 新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
2 明确目标 (编写 items.py):明确你想要抓取的目标,想要爬什么信息
3 制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
4 存储内容 (pipelines.py):设计管道存储爬取内容
具体流程
1、scrapy安装
pip install scrapy<br /><br />Successfully installed Automat-20.2.0 PyDispatcher-2.0.5 Twisted-21.2.0 attrs-21.2.0 constantly-15.1.0 cssselect-1.1.0 h2-3.2.0 hpack-3.0.0 hyperframe-5.2.0 hyperlink-21.0.0 incremental-21.3.0 itemadapter-0.2.0 itemloaders-1.0.4 parsel-1.6.0 priority-1.3.0 protego-0.1.16 pyOpenSSL-20.0.1 pyasn1-0.4.8 pyasn1-modules-0.2.8 queuelib-1.6.1 scrapy-2.5.0 service-identity-21.1.0 twisted-iocpsupport-1.0.1 w3lib-1.22.0 zope.interface-5.4.0
检查是否安装成功:
scrapy versionScrapy 2.5.0
scrapy常用命令使用:
Usage: scrapy [options] [args]<br />Available commands: bench Run quick benchmark test check Check spider contracts commands crawl Run a spider edit Edit spider fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates list List available spiders parse Parse URL (using its spider) and print the results runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy<br />Use "scrapy -h" to see more info about a command
2、创建项目
//创建一个测试项目scrapy startproject scrapyproject<br />New Scrapy project 'scrapyproject', using template directory 'c:\users\username\appdata\local\programs\python\python36\lib\site-packages\scrapy\templates\project', created in: C:\Users\username\PycharmProjects\scrapyproject<br />You can start your first spider with: cd scrapyproject scrapy genspider example example.com
3、第一个爬虫项目
注释:
scrapy genspider -l 查看当前可以使用的爬虫模板
scrapy genspider -t 创建爬虫文件
1.scrapy startproject scrapyproject2.在工程目录下创建爬虫baidu 格式:scrapy genspider [-t template] <br />支持模板template:basic(默认)、crawl、csvfeed、xmlfeed这里name是爬虫的名字;domain是设置allowed_domains以及start_urls,这两个属性可以在爬虫类中修改<br /><br />cd scrapyprojectscrapy genspider baidu baidu.com (baidu 为爬虫的名称,baidu.com为要爬取的网站的域名)<br />输出:Created spider 'baidu' using template 'basic' in module: scrapyproject.spiders.baidu<br />3.使用pycharm 打开第一步创建的项目
目录及文件结构:
文件说明:
scrapy.cfg 项目的配置信息,主要为Scrapy命令行工具提供一个基础的配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py 设置数据存储模板,用于结构化数据,如:Django的Model
pipelines 数据处理行为,如:一般结构化的数据持久化
settings.py 配置文件,如:递归的层数、并发数,延迟下载等
spiders 爬虫目录,如:创建文件,编写爬虫规则
注意:一般创建爬虫文件时,以网站域名命名。
4. cd 项目目录,重写parse函数,然后启动爬虫,命令:
注意ROBOTSTXT_OBEY = False baidu的robots.txt里面禁止了scrapy
scrapy crawl baidu
生成爬取结果
打开是界面:
05Scrapy校花网爬取实践
以校花网为例进行爬取,校花网:
创建xiaohuar spider:
scrapy genspider xiaohuar xiaohuar.comCreated spider 'xiaohuar' using template 'basic' in module: scrapyproject.spiders.xiaohuar
准备:
Python爬虫—破解JS加密的Cookie
网站优化 • 优采云 发表了文章 • 0 个评论 • 285 次浏览 • 2022-05-21 02:21
專 欄
❈Jerry,Python中文社区专栏作者。
blog:
github:
❈前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。
通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。
发现问题
打开Fiddler软件,用浏览器打开目标站点() 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?
仔细观察两次返回的结果可以发现:
1、第二次请求比第一次请求的Cookie内容多了个这个_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
2、第一次返回的内容一些复杂看不懂的JS代码,第二次返回的就是正确的内容
其实这是网站反爬虫的常用手段。大致过程是这样的:首次请求数据时,服务端返回动态的混淆加密过的JS,而这段JS的作用是给Cookie添加新的内容用于服务端验证,此时返回的状态码是521。浏览器带上新的Cookie再次请求,服务端验证Cookie通过返回数据(这也是为嘛代码不能返回数据的原因)。
解决问题
其实我第一次遇到这样的问题是,一开始想的就是既然你是用JS生成的Cookie, 那么我也可以将JS函数翻译成Python运行。但是最后还是发现我太傻太天真,因为现在的JS都流行混淆加密,原始的JS这样的:
<p>function lq(VA) {
var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo] 查看全部
Python爬虫—破解JS加密的Cookie
專 欄
❈Jerry,Python中文社区专栏作者。
blog:
github:
❈前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。
通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。
发现问题
打开Fiddler软件,用浏览器打开目标站点() 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?
仔细观察两次返回的结果可以发现:
1、第二次请求比第一次请求的Cookie内容多了个这个_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe971
2、第一次返回的内容一些复杂看不懂的JS代码,第二次返回的就是正确的内容
其实这是网站反爬虫的常用手段。大致过程是这样的:首次请求数据时,服务端返回动态的混淆加密过的JS,而这段JS的作用是给Cookie添加新的内容用于服务端验证,此时返回的状态码是521。浏览器带上新的Cookie再次请求,服务端验证Cookie通过返回数据(这也是为嘛代码不能返回数据的原因)。
解决问题
其实我第一次遇到这样的问题是,一开始想的就是既然你是用JS生成的Cookie, 那么我也可以将JS函数翻译成Python运行。但是最后还是发现我太傻太天真,因为现在的JS都流行混淆加密,原始的JS这样的:
<p>function lq(VA) {
var qo, mo = "", no = "", oo = [0x8c, 0xcd, 0x4c, 0xf9, 0xd7, 0x4d, 0x25, 0xba, 0x3c, 0x16, 0x96, 0x44, 0x8d, 0x0b, 0x90, 0x1e, 0xa3, 0x39, 0xc9, 0x86, 0x23, 0x61, 0x2f, 0xc8, 0x30, 0xdd, 0x57, 0xec, 0x92, 0x84, 0xc4, 0x6a, 0xeb, 0x99, 0x37, 0xeb, 0x25, 0x0e, 0xbb, 0xb0, 0x95, 0x76, 0x45, 0xde, 0x80, 0x59, 0xf6, 0x9c, 0x58, 0x39, 0x12, 0xc7, 0x9c, 0x8d, 0x18, 0xe0, 0xc5, 0x77, 0x50, 0x39, 0x01, 0xed, 0x93, 0x39, 0x02, 0x7e, 0x72, 0x4f, 0x24, 0x01, 0xe9, 0x66, 0x75, 0x4e, 0x2b, 0xd8, 0x6e, 0xe2, 0xfa, 0xc7, 0xa4, 0x85, 0x4e, 0xc2, 0xa5, 0x96, 0x6b, 0x58, 0x39, 0xd2, 0x7f, 0x44, 0xe5, 0x7b, 0x48, 0x2d, 0xf6, 0xdf, 0xbc, 0x31, 0x1e, 0xf6, 0xbf, 0x84, 0x6d, 0x5e, 0x33, 0x0c, 0x97, 0x5c, 0x39, 0x26, 0xf2, 0x9b, 0x77, 0x0d, 0xd6, 0xc0, 0x46, 0x38, 0x5f, 0xf4, 0xe2, 0x9f, 0xf1, 0x7b, 0xe8, 0xbe, 0x37, 0xdf, 0xd0, 0xbd, 0xb9, 0x36, 0x2c, 0xd1, 0xc3, 0x40, 0xe7, 0xcc, 0xa9, 0x52, 0x3b, 0x20, 0x40, 0x09, 0xe1, 0xd2, 0xa3, 0x80, 0x25, 0x0a, 0xb2, 0xd8, 0xce, 0x21, 0x69, 0x3e, 0xe6, 0x80, 0xfd, 0x73, 0xab, 0x51, 0xde, 0x60, 0x15, 0x95, 0x07, 0x94, 0x6a, 0x18, 0x9d, 0x37, 0x31, 0xde, 0x64, 0xdd, 0x63, 0xe3, 0x57, 0x05, 0x82, 0xff, 0xcc, 0x75, 0x79, 0x63, 0x09, 0xe2, 0x6c, 0x21, 0x5c, 0xe0, 0x7d, 0x4a, 0xf2, 0xd8, 0x9c, 0x22, 0xa3, 0x3d, 0xba, 0xa0, 0xaf, 0x30, 0xc1, 0x47, 0xf4, 0xca, 0xee, 0x64, 0xf9, 0x7b, 0x55, 0xd5, 0xd2, 0x4c, 0xc9, 0x7f, 0x25, 0xfe, 0x48, 0xcd, 0x4b, 0xcc, 0x81, 0x1b, 0x05, 0x82, 0x38, 0x0e, 0x83, 0x19, 0xe3, 0x65, 0x3f, 0xbf, 0x16, 0x88, 0x93, 0xdd, 0x3b];<p> qo = "qo=241; do{oo[qo]=(-oo[qo])&0xff; oo[qo]=(((oo[qo]>>3)|((oo[qo]
一只知乎爬虫
网站优化 • 优采云 发表了文章 • 0 个评论 • 195 次浏览 • 2022-05-15 05:53
本文经作者授权发布。
文 | 程柳锋@Tencent
爬虫的基本流程
网络爬虫的基本工作流程如下:
爬虫的抓取策略
在爬虫系统中,待抓取 URL 队列是很重要的一部分。待抓取 URL 队列中的 URL 以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些 URL 排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:
了解了爬虫的工作流程和爬取策略后,就可以动手实现一个爬虫了!那么在 python 里怎么实现呢?
技术栈基本实现
下面是一个伪代码
<p>import Queue
initial_page = "https://www.zhihu.com/people/gaoming623"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直进行
if url_queue.size()>0:
current_url = url_queue.get() #拿出队例中第一个的 url
store(current_url) #把这个 url 代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个 url 里链向的 url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break</p>
如果你直接加工一下上面的代码直接运行的话,你需要很长的时间才能爬下整个知乎用户的信息,毕竟知乎有 6000 万月活跃用户。更别说 Google 这样的搜索引擎需要爬下全网的内容了。那么问题出现在哪里?
布隆过滤器
需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有 N 个网站,那么分析一下判重的复杂度就是 N*log(N),因为所有网页要遍历一次,而每次判重用 set 的话需要 log(N) 的复杂度。OK,我知道 python 的 set 实现是 hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种 hash 的方法,但是它的特点是,它可以使用固定的内存(不随 url 的数量而增长)以 O(1) 的效率判定 url 是否已经在 set 中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个 url 不在 set 中,BF 可以 100%确定这个 url 没有看过。但是如果这个 url 在 set 中,它会告诉你:这个 url 应该已经出现过,不过我有 2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。
<p># bloom_filter.py
BIT_SIZE = 5000000
class BloomFilter:
def __init__(self):
# Initialize bloom filter, set size and all bits to 0
bit_array = bitarray(BIT_SIZE)
bit_array.setall(0)
self.bit_array = bit_array
def add(self, url):
# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
# Here use 7 hash functions.
point_list = self.get_postions(url)
for b in point_list:
self.bit_array[b] = 1
def contains(self, url):
# Check if a url is in a collection
point_list = self.get_postions(url)
result = True
for b in point_list:
result = result and self.bit_array[b]
return result
def get_postions(self, url):
# Get points positions in bit vector.
point1 = mmh3.hash(url, 41) % BIT_SIZE
point2 = mmh3.hash(url, 42) % BIT_SIZE
point3 = mmh3.hash(url, 43) % BIT_SIZE
point4 = mmh3.hash(url, 44) % BIT_SIZE
point5 = mmh3.hash(url, 45) % BIT_SIZE
point6 = mmh3.hash(url, 46) % BIT_SIZE
point7 = mmh3.hash(url, 47) % BIT_SIZE
return [point1, point2, point3, point4, point5, point6, point7]</p>
BF 详细的原理参考我之前写的文章:布隆过滤器(Bloom Filter) 的原理和实现
建表
用户有价值的信息包括用户名、简介、行业、院校、专业及在平台上活动的数据比如回答数、文章数、提问数、粉丝数等等。
用户信息存储的表结构如下:
<p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
-- User base information table
CREATE TABLE `t_user` (
`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`brief_info` varchar(400) COMMENT '个人简介',
`industry` varchar(50) COMMENT '所处行业',
`education` varchar(50) COMMENT '毕业院校',
`major` varchar(50) COMMENT '主修专业',
`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答数',
`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章数',
`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提问数',
`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏数',
`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被关注数',
`followed_count` int(10) unsigned DEFAULT 0 COMMENT '关注数',
`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '关注直播数',
`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '关注话题数',
`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '关注专栏数',
`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '关注问题数',
`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '关注收藏夹数',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次编辑',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';</p>
网页下载后通过 XPath 进行解析,提取用户各个维度的数据,最后保存到数据库中。
反爬虫策略应对-Headers
一般网站会从几个维度来反爬虫:用户请求的 Headers,用户行为,网站和数据加载的方式。从用户请求的 Headers 反爬虫是最常见的策略,很多网站都会对 Headers 的 User-Agent 进行检测,还有一部分网站会对 Referer 进行检测(一些资源网站的防盗链就是检测 Referer)。
如果遇到了这类反爬虫机制,可以直接在爬虫中添加 Headers,将浏览器的 User-Agent 复制到爬虫的 Headers 中;或者将 Referer 值修改为目标网站域名。对于检测 Headers 的反爬虫,在爬虫中修改或者添加 Headers 就能很好的绕过。
<p>cookies = {
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
"n_c": "1",
"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
"Referer": "https://www.zhihu.com/"
}
r = requests.get(url, cookies = cookies, headers = headers)</p>
反爬虫策略应对-代理 IP 池
还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。
大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理 ip 后可以每请求几次更换一个 ip,这在 requests 或者 urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。目前知乎已经对爬虫做了限制,如果是单个 IP 的话,一段时间系统便会提示异常流量,无法继续爬取了。因此代理 IP 池非常关键。网上有个免费的代理 IP API:
<p>import requests
import random
class Proxy:
def __init__(self):
self.cache_ip_list = []
# Get random ip from free proxy api url.
def get_random_ip(self):
if not len(self.cache_ip_list):
api_url = 'http://api.xicidaili.com/free2016.txt'
try:
r = requests.get(api_url)
ip_list = r.text.split('rn')
self.cache_ip_list = ip_list
except Exception as e:
# Return null list when caught exception.
# In this case, crawler will not use proxy ip.
print e
return {}
proxy_ip = random.choice(self.cache_ip_list)
proxies = {'http': 'http://' proxy_ip}
return proxies</p>
后续
爬虫源代码:zhihu-crawler下载之后通过 pip 安装相关三方包后,运行$ python crawler.py 即可(喜欢的帮忙点个 star 哈,同时也方便看到后续功能的更新)
运行截图:
查看全部
一只知乎爬虫
本文经作者授权发布。
文 | 程柳锋@Tencent
爬虫的基本流程
网络爬虫的基本工作流程如下:
爬虫的抓取策略
在爬虫系统中,待抓取 URL 队列是很重要的一部分。待抓取 URL 队列中的 URL 以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些 URL 排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:
了解了爬虫的工作流程和爬取策略后,就可以动手实现一个爬虫了!那么在 python 里怎么实现呢?
技术栈基本实现
下面是一个伪代码
<p>import Queue
initial_page = "https://www.zhihu.com/people/gaoming623"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直进行
if url_queue.size()>0:
current_url = url_queue.get() #拿出队例中第一个的 url
store(current_url) #把这个 url 代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个 url 里链向的 url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break</p>
如果你直接加工一下上面的代码直接运行的话,你需要很长的时间才能爬下整个知乎用户的信息,毕竟知乎有 6000 万月活跃用户。更别说 Google 这样的搜索引擎需要爬下全网的内容了。那么问题出现在哪里?
布隆过滤器
需要爬的网页实在太多太多了,而上面的代码太慢太慢了。设想全网有 N 个网站,那么分析一下判重的复杂度就是 N*log(N),因为所有网页要遍历一次,而每次判重用 set 的话需要 log(N) 的复杂度。OK,我知道 python 的 set 实现是 hash——不过这样还是太慢了,至少内存使用效率不高。
通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是一种 hash 的方法,但是它的特点是,它可以使用固定的内存(不随 url 的数量而增长)以 O(1) 的效率判定 url 是否已经在 set 中。可惜天下没有白吃的午餐,它的唯一问题在于,如果这个 url 不在 set 中,BF 可以 100%确定这个 url 没有看过。但是如果这个 url 在 set 中,它会告诉你:这个 url 应该已经出现过,不过我有 2%的不确定性。注意这里的不确定性在你分配的内存足够大的时候,可以变得很小很少。
<p># bloom_filter.py
BIT_SIZE = 5000000
class BloomFilter:
def __init__(self):
# Initialize bloom filter, set size and all bits to 0
bit_array = bitarray(BIT_SIZE)
bit_array.setall(0)
self.bit_array = bit_array
def add(self, url):
# Add a url, and set points in bitarray to 1 (Points count is equal to hash funcs count.)
# Here use 7 hash functions.
point_list = self.get_postions(url)
for b in point_list:
self.bit_array[b] = 1
def contains(self, url):
# Check if a url is in a collection
point_list = self.get_postions(url)
result = True
for b in point_list:
result = result and self.bit_array[b]
return result
def get_postions(self, url):
# Get points positions in bit vector.
point1 = mmh3.hash(url, 41) % BIT_SIZE
point2 = mmh3.hash(url, 42) % BIT_SIZE
point3 = mmh3.hash(url, 43) % BIT_SIZE
point4 = mmh3.hash(url, 44) % BIT_SIZE
point5 = mmh3.hash(url, 45) % BIT_SIZE
point6 = mmh3.hash(url, 46) % BIT_SIZE
point7 = mmh3.hash(url, 47) % BIT_SIZE
return [point1, point2, point3, point4, point5, point6, point7]</p>
BF 详细的原理参考我之前写的文章:布隆过滤器(Bloom Filter) 的原理和实现
建表
用户有价值的信息包括用户名、简介、行业、院校、专业及在平台上活动的数据比如回答数、文章数、提问数、粉丝数等等。
用户信息存储的表结构如下:
<p>CREATE DATABASE `zhihu_user` /*!40100 DEFAULT CHARACTER SET utf8 */;
-- User base information table
CREATE TABLE `t_user` (
`uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`brief_info` varchar(400) COMMENT '个人简介',
`industry` varchar(50) COMMENT '所处行业',
`education` varchar(50) COMMENT '毕业院校',
`major` varchar(50) COMMENT '主修专业',
`answer_count` int(10) unsigned DEFAULT 0 COMMENT '回答数',
`article_count` int(10) unsigned DEFAULT 0 COMMENT '文章数',
`ask_question_count` int(10) unsigned DEFAULT 0 COMMENT '提问数',
`collection_count` int(10) unsigned DEFAULT 0 COMMENT '收藏数',
`follower_count` int(10) unsigned DEFAULT 0 COMMENT '被关注数',
`followed_count` int(10) unsigned DEFAULT 0 COMMENT '关注数',
`follow_live_count` int(10) unsigned DEFAULT 0 COMMENT '关注直播数',
`follow_topic_count` int(10) unsigned DEFAULT 0 COMMENT '关注话题数',
`follow_column_count` int(10) unsigned DEFAULT 0 COMMENT '关注专栏数',
`follow_question_count` int(10) unsigned DEFAULT 0 COMMENT '关注问题数',
`follow_collection_count` int(10) unsigned DEFAULT 0 COMMENT '关注收藏夹数',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次编辑',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';</p>
网页下载后通过 XPath 进行解析,提取用户各个维度的数据,最后保存到数据库中。
反爬虫策略应对-Headers
一般网站会从几个维度来反爬虫:用户请求的 Headers,用户行为,网站和数据加载的方式。从用户请求的 Headers 反爬虫是最常见的策略,很多网站都会对 Headers 的 User-Agent 进行检测,还有一部分网站会对 Referer 进行检测(一些资源网站的防盗链就是检测 Referer)。
如果遇到了这类反爬虫机制,可以直接在爬虫中添加 Headers,将浏览器的 User-Agent 复制到爬虫的 Headers 中;或者将 Referer 值修改为目标网站域名。对于检测 Headers 的反爬虫,在爬虫中修改或者添加 Headers 就能很好的绕过。
<p>cookies = {
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"login": "NzM5ZDc2M2JkYzYwNDZlOGJlYWQ1YmI4OTg5NDhmMTY=|1480901173|9c296f424b32f241d1471203244eaf30729420f0",
"n_c": "1",
"q_c1": "395b12e529e541cbb400e9718395e346|1479808003000|1468847182000",
"l_cap_id": "NzI0MTQwZGY2NjQyNDQ1NThmYTY0MjJhYmU2NmExMGY=|1480901160|2e7a7faee3b3e8d0afb550e8e7b38d86c15a31bc",
"d_c0": "AECA7v-aPwqPTiIbemmIQ8abhJy7bdD2VgE=|1468847182",
"cap_id": "N2U1NmQwODQ1NjFiNGI2Yzg2YTE2NzJkOTU5N2E0NjI=|1480901160|fd59e2ed79faacc2be1010687d27dd559ec1552a"
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.3",
"Referer": "https://www.zhihu.com/"
}
r = requests.get(url, cookies = cookies, headers = headers)</p>
反爬虫策略应对-代理 IP 池
还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。
大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理 ip 后可以每请求几次更换一个 ip,这在 requests 或者 urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。目前知乎已经对爬虫做了限制,如果是单个 IP 的话,一段时间系统便会提示异常流量,无法继续爬取了。因此代理 IP 池非常关键。网上有个免费的代理 IP API:
<p>import requests
import random
class Proxy:
def __init__(self):
self.cache_ip_list = []
# Get random ip from free proxy api url.
def get_random_ip(self):
if not len(self.cache_ip_list):
api_url = 'http://api.xicidaili.com/free2016.txt'
try:
r = requests.get(api_url)
ip_list = r.text.split('rn')
self.cache_ip_list = ip_list
except Exception as e:
# Return null list when caught exception.
# In this case, crawler will not use proxy ip.
print e
return {}
proxy_ip = random.choice(self.cache_ip_list)
proxies = {'http': 'http://' proxy_ip}
return proxies</p>
后续
爬虫源代码:zhihu-crawler下载之后通过 pip 安装相关三方包后,运行$ python crawler.py 即可(喜欢的帮忙点个 star 哈,同时也方便看到后续功能的更新)
运行截图: