Python爬虫学习-爬取大规模数据(10w级)

编译环境:python v3.5.0, mac osx 10.11.4
<big>python爬虫基础知识: Python爬虫学习-基础爬取</big>

了解数据库 MongoDB

  • 数据库是储存数据的地方,可以将如下的字典结构插入到MongoDB的存储单元中。
    data = {
    'name':peter
    'id':123
    ...
    } # 需存储的文件
  • 数据库的构成:可以将其类比于excel表格进行理解
    client = pymongo.MongoClient('localhost',27017) # 将python与mongodb进行连接,'localhost'表示本地环境, 207017是端口号
    walden = client['walden'] # 创建一个库文件
    以上代码可以类似于创建一个excel文件,文件名为walden



    sheet_tab = walden['sheet_tab'] # 在库文件中建立一个页面名叫 sheet_tab
    以上代码可以类似于创建excel文件中的一个表单


  • 数据库的基本操作:
    1. 向页边中插入数据:sheet_tab.insert_one(data)
      其中data为python中的字典结构,可有如下代码生成:
      path = './walden.txt' # 输入数据的路径,为读取数据做准备
      with open(path,'r') as f: # 打开文件,为只读模式
      lines = f.readlines()
      for index,line in enumerate(lines): # 逐个生成字典元素
      data = {
      'index':index,
      'line' :line,
      'words':len(line.split())
      }
      sheet_tab.insert_one(data) # 将字典元素插入库文件页面中
  1. 筛选数据库中的数据(基础筛选)
    sheet_tab.find({'words':{'$lt':5}} # 选择字典中关键字words对应值小于5的所有字典元素
    # $lt/$lte/$gt/$gte/$ne,依次等价于</<=/>/>=/!=。(l表示less g表示greater e表示equal n表示not )

基础实战(筛选房源)

筛选小猪短租网站前三页信息储存到MongoDB中,筛选出价格大于等于500元房源,并打印出来。房源信息具体要求如下:

  • <big>实战源码</big> (下载地址xiaozhu.py
    # -- coding: utf-8 --
    import requests, time, pymongo
    from bs4 import BeautifulSoup
    def gender_info(soup): # 获取性别信息
    gender = 'female' if soup.find_all('div','div.member_ico1') else 'male'
    return gender
    def get_info(url): # 获取所需的房源信息
    wb_data = requests.get(url) # 向服务器请求页面
    wb_data.encoding ='utf-8' # 标明编码为utf-8,以免出现解码错误
    soup = BeautifulSoup(wb_data.text,'lxml') # 以lxml方式对页面进行解析
    title = soup.select('h4 em')[0].text
    address = soup.select('span.pr5')[0].text
    price = int(soup.select('div.day_l span')[0].text)
    img = soup.select('#curBigImage')[0].get('src')
    hostPic = soup.select('#floatRightBox > div.js_box.clearfix > div.member_pic > a > img')[0].get('src')
    hostName = soup.select('#floatRightBox > div.js_box.clearfix > div.w_240 > h6 > a')[0].text
    hostGender = gender_info(soup)
    data = {
    'title' : title,
    'address': address,
    'price' : price,
    'img' :img,
    'hostPic' : hostPic,
    'hostName' : hostName,
    'hostGender' : hostGender
    }
    print('get_info Done')
    return data
    def get_list_url(pageURL): # 获取页面中所有详细房源的url
    listUrl = []
    wb_data = requests.get(pageURL)
    wb_data.encoding = 'utf-8'
    soup = BeautifulSoup(wb_data.text,'lxml')
    pageList = soup.select('div.result_btm_con.lodgeunitname')
    for i in pageList:
    listUrl.append(i.get('detailurl'))
    print('get_list_url Done')
    return listUrl
    def get_info_by_page(startPage, endPage, baseURL,database): # 获取整个页面的信息
    for i in range(startPage,endPage+1):
    url = baseURL.format(i)
    listUrl = get_list_url(url)
    for j in listUrl:
    time.sleep(4)
    dataInfo = get_info(j) # 获取每个页面的信息
    database.insert_one(dataInfo) # 将信息插入到指定的页面中
    print('input to database Done')
    client = pymongo.MongoClient('localhost',27017) # 连接mongodb
    xiaozhu = client['xiaozhu'] # 创建一个名叫xiaozhu的库文件
    home_info = xiaozhu['home_info'] # 创建一个home_info的页面
    pageBaseUrl = 'http://bj.xiaozhu.com/search-duanzufang-p{}-0/' # 构造共同url连接
    get_info_by_page(1,3,pageBaseUrl,home_info) # 调用函数爬取信息并将信息储存到mongodb中
    for info in home_info.find({'price':{'$gte':500}}): # 打印大于等于500的房源信息
    print(info)
  • <big>结果展示</big>
    mongoDB中的储存结果(部分截图)
    价格大于等于500的房源信息(部分截图)

爬取工作分析流程

<big>1. </big>观察页面特征,保证爬虫程序的通用性,即:发现边界条件和局限性。
例:爬取赶集网-北京二手市场的所有类目中属于<big>个人</big>的商品信息。

  • 观察的到页面(url)变动的信息


  • 发现页面变动边界条件
    1. 当把页面设定到150页时,我们发现返回的页面是任意四件商品的信息。因此,我们要据此,判断我们所爬取的页面是否已经到头。避免重复的信息加入到我们的数据库中。
    2. 并且通过观察发现网站这一返回操作,我们发现正常页面中有列表链接可以点击,而由于页面超出范围返回的随机商品信息页面没有。
    3. 因此我们可以用BeautifulSoup库中的find方法实现这个操作。
      soup.find('ul', 'pageLink') #找到返回TRUE,没有返回FALSE
  • 一般这种交易网站,当商品卖出后,商品有关信息页面将会被删除,所以我们爬取的过程中,可能将有商品被卖出,当我们向服务器进行请求该商品详情界面时会出现404 not found。我们可以通过status_code的方法对页面进行判断。
    wb_data.status_code == 404 # 判断商品是否已被卖出,卖出则返回TRUE,没有则返回FALSE

<big>2. </big>设计工作流程,保证输出效率和稳定性。

  • 分步进行:先获取channel_list(所有频道分类的URL),保证爬取的稳定性。若是爬取类目信息,与爬取商品信息同步进行的话,当程序出现错误时,我们则什么信息也不能得到。所以分步进行可以降低风险。(图中分类项目下的所有商品详情链接)

  • 多进程爬取: 可以利用multiprocess库中的pool函数,进行多进程爬取,这样可以提高爬取的效率。
    关于进程与线程:
    可以理解成多个人完成吃饭这个工作的效率:
    单线程单进程:只有一个餐桌,一个人在一个餐桌上吃饭,每个人依次进行。
    单线程多进程:有多个餐桌,每个餐座上只有一个人在吃饭。
    单进程多线程: 只有一个餐桌,一个餐桌上可以坐多个人。
    多进程多线程:多个餐座,一个餐桌上可以坐多个人。

  • 对项目进行监测:
    我们可以设计一个检测函数,隔一段时间汇报所抓取信息的数量,对项目进程进行掌控。
    import timeframe page_parsing
    import url_list
    while True:
    print(url_list.find().count())
    time.sleep(5)

  • 设计断点续传程序:
    由于在我们抓取的过程中可能会遇到网络问题,导致程序终止,而我们不希望重新开始抓取,而是在中断后的地方继续进行抓取。

    设计思路如下:

    1. 数据库中建立两个页面存放详情商品链接(从这一点也可以看出分步抓取的重要性)。一个存放需要抓取的(url_list1)一个存放已经抓取网商品信息的 (url_list2)。
  1. 当中断后继续抓取时,url_list1-url_list2就是剩下带抓取的商品信息页面。
    db_urls = [item['url'] for item in url_list.find()] # 用列表解析式装入所有要爬取的链接
    index_urls = [item['url'] for item in item_info.find()] # 所引出详情信息数据库中所有的现存的 url 字段
    x = set(db_urls) # 转换成集合的数据结构
    y = set(index_urls)rest_of_urls = x-y # 剩下的url

爬取结果以及源码(按设计步骤展示)

**All source code **: JacobKam-GitHub

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

推荐阅读更多精彩内容