美文网首页pythonPythonpython爬虫升级之路
Python爬虫学习-爬取大规模数据(10w级)

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

作者: 掷骰子的求 | 来源:发表于2016-05-13 17:10 被阅读9658次

    编译环境: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

    相关文章

      网友评论

      • Think4doing:挺详细
      • VB过得VB:够我个新人研究一天的了😳
      • mugichya:断点续传我试过不对,不知道为什么,就成死循环了,你的简书这里还有GitHub上都没有断点续传的源码是吧?
        掷骰子的求:@mugichya 文章里有写
      • 5b674470f1cd:赞一个,确实很详细,非常好
        掷骰子的求:@混江龙 谢谢
      • 5b674470f1cd::+1:好详细,谢谢!
      • chenchao981:代码只抓链接,item info 数据库没有写入吧
        十里之_外:@掷骰子的求 您好,我有两个问题想问一下,第一个问题,在后面添加一个pool抓item_info到mongodb数据库中的时候,是当前面一个抓10万链接的pool全部执行完后才执行第二个pool,还是说两个pool可以同步执行? 第二个问题,如果现在在mongodb中已经存有现成的2万链接,如何从mongodb中调用这些链接,然后抓取item_info再存入mongodb中,我不太懂直接从mongodb中调用数据这个过程,非常感谢:pray:
        掷骰子的求:@chenchao981 是的,再在后面添加一个pool抓item就好了

      本文标题:Python爬虫学习-爬取大规模数据(10w级)

      本文链接:https://www.haomeiwen.com/subject/xzyerttx.html