Python+requests+bs4+ponyORM 抓取拉勾网数据

自从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或者在下面评论,欢迎交流~