多线程爬取+MongoDB+Highcharts

第一次上kaggle来做实训,第一印象界面美观,向导友好,难怪有那么多人来推荐。数据集也很丰富,有关于欧洲足球的,美国总统竞选的,计算机语言使用调查的,人力资源分析,历史上的飞机事故统计,IMDB电影的数据分析,还有些脱敏的金融借贷信息。
找到了Titanics数据集,跟着向导第一次做任务,datacamp中的课程有任务说明,可以根据提示写代码,然后提交,错误还可以根据提示进行修正,直到教会你为止。感觉和以前打一个新游戏的任务向导很像。

![RC1@DRW[75)(ADBLGPK_)Q.png计划年底前搭建一个数据分析平台,运用Python爬虫获得数据,存在MongoDB数据库中,导出数据到SAS进行数据挖掘,结果用HighCharts或者Matplotlib做数据可视化展示,最后放在基于Django开发的网站上。
在爬取内容上可以先选择招聘信息,房价信息,失信人名单(需要selenium)

初期目标先不考虑数据挖掘部分,数据挖掘需要单独研究,把平台架构完成,只包括爬取,存储和展示。

需求:

  1. 多线程爬取58同城二手信息以及详细内容
  2. 存储到MongoDB
  3. 运用highcharts展示

思路

  1. 爬取
    分成两部分,第一部分先把网站上各个分类各种分页的链接都爬取下来,保存在数据库中。第二部分逐一读取每个链接,访问详细页信息并且爬取并存储。

  2. 存储
    选择Mongodb数据库是因为它和传统数据库相比更加符合OLAP的原则,是面向分析和维度的数据库,可以更好的对列进行操作而不是行记录,更加适合数据量大的分析工作。备份一个维度为10的20万条记录大约5-8秒。

  3. 首先展示数据可视化无法在pycharm上进行,必须用安装jupyter来工作。然后,由于Highcharts是用jquery开发的,所以有固定格式,必须把数据库中的信息自动生成列表形式才能展现。
    实现一个用图表展示按区域统计发帖数量

代码和结果:

  1. 爬取


    666.png

    888.png
  2. 存储

555.png
777.png

3.展示

333.png
444.png

经验与难点:

  1. 爬取
    a). 爬取过程中发现有些商品已经下架,造成信息无法正确提取,爬取中断。

为了解决这个问题需要判断一下页面上的一些提示信息,具体如下:
no_longer_exist = '商品已下架' in soup.select('.button_li')[0].text
if no_longer_exist:
print("商品已下架:" + url)
else:
codes to be executed

b). 爬取过程中发现其实这个网站经过改版,同时存在两种类型的详情页,一种是58转转的,一种是极个别的老的网页。当爬到老的网页时,由于元素位置和名称和转转结构不一致造成报错。

为了排除这些错误,在执行代码
加了try...except异常处理。
try:
codes to be executed
except(IndexError):
print("index error")

c). 当爬取中断的时候想断点续爬,比如想爬10万条,爬了5万条遇到错误中断,想避免之前的重复爬取,而是接着5万条继续爬取。

先访问数据库中的链接数据列表,得到所有的链接全集内容。
然后访问详情页中已经爬取的链接列表。然后分别把他们放到集合中,再将两个集合相减,由于集合相减做的是差运算,得到的结果就是那些还没有爬取的链接内容,然后进行爬取。
db_urls = [item["url"] for item in url_list.find()]
index_urls = [item["url"] for item in item_info.find()]
x = set(db_urls)
y = set(index_urls)
rest_of_urls = x - y
这边用了一个循环列表表达式,据说性能是原来for循环的10倍,所有的循环赋值语句都可以使用,是一个不错的提高性能的小技能。

d). 提高性能,使用多线程进行操作

首先创建一个线程池对象,并且把处理器参数设置成等于PC的CPU个数,注意过多或者过少设置处理器参数都不能最大化的优化处理速度。然后使用map函数或者process函数对链接和详细页分别进行爬取。
使用多线程技术以后,爬取速度是原来的200-300%,链接列表爬取每小时8万条,详情页大概每小时2万条。

如果还想进一步提升性能,可以在解析网页的时候不使用BeautifulSoup函数,而是直接用lxml来解析,速度可以提升8-10倍。但是考虑网站负载问题,速度和安全性相比,肯定还是需要更加安全小心的去爬取。

e). 由于这些二手发布网站的网站性能较好,没有刻意的对爬虫进行封锁,但是为了安全起见还是应该对Header,cookies以及agent进行伪装?;蛘呖梢越兴婊籶roxy代理ip来访问网站。

headers = {'UserAgent':'Mozilla/5.0 (Windows NT 5.1; rv:37.0) Gecko/20100101 Firefox/37.0'}
proxy_list =
[
'http://117.177.250.151:8081',
'http://111.85.219.250:3129',
'http://122.70.183.138:8118',
]
proxy_ip = random.choice(proxy_list)
proxies = {'http':proxy_ip}

f). 还有些细节,比如爬取访问量和购买数量的时候会带一些中文字符,而不是纯数字,比如“201次浏览”,"【9图】"等。
为了提取数字,可以使用
view = soup.select('.look_time')[0].text.split("次浏览")[0]
pic_num = title.split('图')[0].split("【")[1]
这样在爬取端就解决了数据格式的问题,比在后期在数据库端解决相对容易。

  1. 存储
    a). 由于担心误操作,把辛辛苦苦哭花了10几个小时爬取的数据给更新错误,所以做任何数据库操作之前需要对数据库进行备份。
222.png

b). Mongodb数据库不是基于SQL语言进行查询的,而是面向对象的操作,所有的操作都需要重新学习。
http://www.runoob.com/mongodb/mongodb-tutorial.html
详情参见上述网页

  1. 展示
    a). 首先是需要安装charts库和安装网页编辑器jupyter库(这个东东可以代替pycharm进行IDE开发),然后要去配置jupyter服务器,并且登录上。
    http://localhost:8888/tree#
    在命令行里输入:jupyter notebook,自动运行网页编辑器,然后新建一个python3文件。
    shift+enter是执行
99.png

然后在网页上可以直接生成图表

aa.png

b). 由于highcharts是用jquery开发,所以有一定的格式需要遵循,意味着要进行格式转换。
读取数据库文件然后用程序来自动生成。
def data_gen(types):
length = 0

if length <= len(area_index):

if length <= len(area_index):
    for area,times in zip(area_index,post_time):
        data={
            "name":area,
            "data":[times],
            "type":types
        }
        yield data
        length += 1

series = [data for data in data_gen("column")]
charts.plot(series, show='inline',options=dict(title=dict(text='statics')))

这里的难点是yield函数,就是生成器函数,这个是python比较中特殊的机制。
http://www.cnblogs.com/tqsummer/archive/2010/12/27/1917927.html
“生成器函数在Python中与迭代器协议的概念联系在一起。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的作用是用来yield产生值的。

不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效”
简而言之作用就是减少python的内存开销,更加高效快速地执行运算操作。

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容