自从14年底开始接触Python,到现在也已经一年多了。期间因为自己的各种拖延症,导致我学Python学的超级慢。光是一本《Python核心编程》就看了大半年还没看完,一直在犹豫学这个学那个,导致自己虽然接触的东西很多,前端后端都有,但是都学得很浅,想要做出个完完整整的东西还是很困难。这次的爬虫是一次很棒的练手项目,Python多线程提高了抓取和存储效率,requests+BeautifulSoup搭档来请求并解析网页,pony ORM简化数据的存储,接下来就是准备用Flask做后端框架来用起我抓取的这些信息了。

  1. requests

    请求网页Python有自带的urllib和urllib2,但是非常的不好用。论简便好用还是要选择requests,如果要发起请求,只需要:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
      # GET请求
      requests.get('http://www.baidu.com')
      # POST请求(没有表单提交)
      requests.post(url)
      # 拉勾的职位信息可以在调试器里面找到ajax加载的json文件
      # json文件可以通过构造post请求来获取指定的职位信息
      data = {
        'kd': kd,
        'pn': pn,
        'px': new
      }
      headers = {'User-Agent': '*******'}
      requests.post(url, data=data, headers=headers).json()
      # kd是职位关键词,pn是页数,可以在请求的json文件中看到kd职位总共有totalPageCount页
    

    更多的关于requests的内容详见 requests文档

  2. BeautifulSoup

    关于如何安装bs的教程无论是baidu还是google都很多,这里简单介绍下它的用法。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
        import requests
        from bs4 import BeautifulSoup
        # 构造一个BeautifulSoup对象,解析器使用lxml
        page = requests.get('http://www.lagou.com')
        bs = BeautifulSoup(page.content, 'lxml')
        print(bs.prettify())
        # 查找内容,找出所有class为'menu_sub'的div
        menus = bs.find_all('div', class_='menu_sub')
        # 在chrome调试器中我们可以找到主页里职位列表在class为menu_sub的div中的dl>dd>a中
        # 选出对应的a标签
        atags = menus.select('dl dd a')
        # 要获得a标签中的内容只需要使用atags[0].string就可以
        for a in atags:
            print(a.string.strip())
    

    其它的页面的内容的获取方式类似就可以,BeautifuSoup很强大,更多的方法技巧请参见:BeautifulSoup文档

  3. pony ORM

    之前一直在纠结如何存数据库的问题,因为自己构造sql语句来存储实在是太累了。。为了偷懒,找到了这个强大的ORM框架!可以用Python的方式来使用数据库。而pony ORM的使用方式文档中说的很清楚了,感兴趣的朋友可以去看看文档,详见ponyORM文档 而在我的项目中pony的使用在lagouDb.py文件中,github地址在文章结尾。

  4. Python多线程: threading

    多线程在爬虫里面可以极大的加快爬去速度,因为爬虫的主要耗时在请求页面和存储数据库两个阶段,如果在请求等待页面的过程中,继续请求下一个页面,等页面响应之后在去处理页面就可以加快爬虫的抓取速度。 在Python里面使用多线程,可以使用threading模块。编写继承threading.Thread的类并实现run方法,就可以开启多线程。多线程的使用一般和队列结合再一起,可以使用queue模块

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
        import threading
    
    
        class ThreadCrawl(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)
                pass
    
            def run(self):
                pass
    

    threading模块的使用可以参考廖雪峰老师的教程或者直接看文档

具体的抓取代码我放在了github,地址:Crawler-lagou 如果有问题请直接提issue或者在下面评论,欢迎交流~