小试牛刀——自己的第一个爬虫实践

文集名字已经改成《蜘蛛结网》了,那么这个专题下不限于课程学习的练习题,也有自己的练手和札记。
最近去爬了一个留学服务网站,主要汇集了美国私立中学的信息,学习爬虫不久,不过凭这门语言的经验和一些小技巧基本能搞定。

网站主页

点击“院校”链接进入可以看到诸如所在州,城市,宗教等分类可供筛选。

频道页面

-------------------------------------Channel 入口----------------------------------------

爬取的思路就是按州的分类来爬取,从URL中可以发现美国各州的缩写包含在里面,那么就把所有州放入最初的state_list里面:
state_list = '''
MA
CT
... # 有省略,米国所有州缩写
'''
----------------------------------------Link列表的获取-----------------------------------
然后就在base_url的基础上编辑每个州所有学校所在页面的URL:

    for page in range(1, page_num):
        school_page = base_url + state + '&page=' + str(page)

这样就可以写一个get_school_link(state_list)函数获取所有州下全部学校的link("href"标签)。注意到页面有每页显示10条,20条,50条记录数等,这样也可以设定我们最初的URL,这个网站上的所有学校数目是可以看到的,因此也就知道每页50条记录的话,page的数目设为50就绰绰有余了。当然也可以通过最后一页无信息的特定标签来确定爬取页面到头了。
把所有学校的link插入MongoDB数据库中,后续调用爬取每个URL的页面,并且也可以作为断点续传时候总的集合:

school_list_total.insert_one({'school_link': school_link})

------------------------------------------单个页面的爬取------------------------------------

单个页面详情

要获取的学校信息较多,分别在“概况”,“学术”,“周边”等link下,因此将每个link分别写了一个函数准备爬取的时候调用:
学校概况(base_info(url)):
将爬出的数据存入字典base_data中:

    base_data = {
        '学校名称': cn_name,
        '英文名称': eg_name,
        '学校介绍': introduction[0].get_text().strip(),
        '学校类型': school_type,
        '建校时间': build_time[0].get_text(),
        ... # 更多信息省略,strip()是一个很好用的方法,去除字符串之间的空格
        '教师学历': tuition[6].get_text().strip() + '硕士以上',
        'SAT分数': tuition[7].get_text().strip(),
    }

当然为防止出错,也要用异常处理的(try-except),否则程序跑着可能因为IndexError,ConnectionError等等类似问题停下,可能是由于网页中对应的内容没有,如果没有我们就在except中将这个内容设为'N/A'。

其他相应的有AP_course(url),society_structure(url),uni_college_list(url), summer_school(url)等函数,分别存入字典course_data, society_info_data,society_info_data, uni_college_data, summer_school中,Python3.X里面字典的操作有合并更新一项,因此几个字典可以合并一起插入数据库中存储。

def get_info(school_link):

try:
    data = {'school_link': school_link}
    base_data = base_info(school_link)  # 学校基本信息
    data.update(base_data)  # 将学校信息在data中更新
    course_data = course_info(school_link + '/academia')  # AP课程信息
    data.update(course_data)
    uni_college_data = uni_college_info(school_link + '/academia')  # 升学信息
    data.update(uni_college_data)
    society_data = society_info(base_url + school_link.split('/')[-1] + '/area')  # 社会信息
    data.update(society_data)
    summer_school_data = summer_school(base_url + school_link.split('/')[-1] + '/summerschool')  # 夏校信息
    data.update(summer_school_data)
    get_info_1.insert_one(data)  # 将学校信息插入数据库
    print(school_link)

except (ConnectionError, ConnectionAbortedError):
    pass

前面有所有学校的URL,这里我们爬取一所学校就存入一条完成的URL,如果中途服务器连接中断就可以提取未爬过URL(两者的差集)的断点续传:

 db_urls = [item['school_link'] for item in school_list_total.find()]
 index_urls = [item['school_link'] for item in get_info_1.find()]
x = set(db_urls)
y = set(index_urls)
rest_of_list = x-y

最后当然要用上proxy(最好有一个列表从里面随机取),headers,time.sleep()这些小技巧应对反爬,进程池可以提高爬取效率,这样就可以顺利获得想要的数据了。同时可以写个小程序统计所用的时间和爬取的数据数目,此处略去一万字。

-----------------------------------------把数据导出来-----------------------------------------
爬完之后数据是存储在MongoDB中的呀,如图所示:

学校详情存入了数据库
只显示前300条,放心其实数据都存进去了

我们想要这些数据为我们后续所用(这里比如我想看到全部的数据啊),那就导出,导出成json格式和csv格式都非常方便。只是注意导出成csv的时候需要指定字段名称才能导出相应字段,而且打开后可能有乱码,可以先用notepad++打开再改为ANSI编码(csv编码格式),然后保存为csv就没有问题了。

导出到csv的数据

----------------------------------最后的分割线--------------------------------------------------------

这次的对代码块的样式有了改进,前面有网友吐槽排版,这次终于找到正确的打开方式了,附上一篇简书上详细教程
//www.greatytc.com/p/q81RER

小试牛刀,学无止境,不敢偷懒,后面还是会继续学习更新的。

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

推荐阅读更多精彩内容