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

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

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

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

  • 数据库的基本操作:
    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元房源,并打印出来。房源信息具体要求如下:

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

  • <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中的储存结果(部分截图) 《Python爬虫学习-爬取大规模数据(10w级)》 价格大于等于500的房源信息(部分截图) 《Python爬虫学习-爬取大规模数据(10w级)》

爬取工作分析流程

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

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

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

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

  • 发现页面变动边界条件
    1. 当把页面设定到150页时,我们发现返回的页面是任意四件商品的信息。因此,我们要据此,判断我们所爬取的页面是否已经到头。避免重复的信息加入到我们的数据库中。 《Python爬虫学习-爬取大规模数据(10w级)》

    2. 并且通过观察发现网站这一返回操作,我们发现正常页面中有列表链接可以点击,而由于页面超出范围返回的随机商品信息页面没有。 《Python爬虫学习-爬取大规模数据(10w级)》 《Python爬虫学习-爬取大规模数据(10w级)》

    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),保证爬取的稳定性。若是爬取类目信息,与爬取商品信息同步进行的话,当程序出现错误时,我们则什么信息也不能得到。所以分步进行可以降低风险。(图中分类项目下的所有商品详情链接)

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

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

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

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

    《Python爬虫学习-爬取大规模数据(10w级)》 设计思路如下:

    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

    原文作者:掷骰子的求
    原文地址: https://www.jianshu.com/p/5f5cfefd7f1d
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞