zoukankan      html  css  js  c++  java
  • 爬虫——使用BeautifulSoup4的爬虫

    我们以腾讯社招页面来做示例:http://hr.tencent.com/position.php?&start=0#a

    如上图,使用BeautifulSoup4解析器,将图1中229页,每页10个招聘信息,共2289个招聘信息中的职位名称、职位类别、招聘人数、工作地点、工作职责、工作要求、详情链接等信息存储在本地磁盘(如下图)。

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    __author__ = 'mayi'
    
    """
    案例:使用BeautifulSoup4爬取腾讯招聘页面的数据
    url:http://hr.tencent.com/position.php?&start=10#a
    使用BeautifulSoup4解析器,爬取每个招聘详情页面里面的:
    职位名称、工作地点、职位类别、招聘人数、工作职责、工作要求、url链接
    """
    
    from bs4 import BeautifulSoup
    import urllib.request
    import json
    
    
    # 创建一个爬虫类
    class TencentSpider(object):
        """
        一个爬虫类:爬取腾讯招聘页面信息
        """
        def __init__(self):
            """
            初始化函数
            :return:
            """
            # User-Agent头
            self.header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}
            self.url = "http://hr.tencent.com/"
            self.file_name = open("tencent.txt", "w", encoding = "utf-8")
    
            # 爬虫开始工作
            self.run()
    
        def run(self):
            """
            爬虫开始工作
            :return:
            """
            # 首页
            start_page = 1
            # 尾页
            end_page = self.getLastPage(self.url + "position.php?&start=0#a")
            # 循环处理每一页
            for page in range(start_page, end_page + 1):
                print("正在处理第" + str(page) + "页")
                # 每一页有10个招聘信息
                pn = (page - 1) * 10
                # 接接成完整的url地址
                full_url = self.url + "position.php?&start=" + str(pn) + "#a"
                # 获取招聘详情链接:l square
                link_list = self.getPositons(full_url)
                for link in link_list:
                    # 拼接成完整的链接
                    full_link = self.url + link
                    # 获取招聘信息页面里的所需爬取的信息
                    self.getPositionInfo(full_link)
    
            # 关闭文件
            self.file_name.close()
    
        def getLastPage(self, url):
            """
            获取尾页的page值
            :param url: 首页的url地址
            :return: 尾页的page值
            """
            # 获取url页面的内容:bytes
            html = self.loadPage(url)
            # bytes转utf-8
            html = html.decode("utf-8")
            # 创建 Beautiful Soup 对象,指定lxml解析器
            soup = BeautifulSoup(html, "lxml")
            page_nav = soup.select('div[class="pagenav"]')[0]
            page = page_nav.find_all('a')[-2].get_text()
    
            return int(page)
    
        def loadPage(self, url):
            """
            获取url页面的内容
            :param url: 需要获取内容的url地址
            :return: url页面的内容
            """
            # url 连同 headers,一起构造Request请求,这个请求将附带 chrome 浏览器的User-Agent
            request = urllib.request.Request(url, headers = self.header)
            # 向服务器发送这个请求
            response = urllib.request.urlopen(request)
            # time.sleep(3)
            # 获取网页内容:bytes
            html = response.read()
    
            return html
    
        def getPositons(self, url):
            """
            获取url页面内的招聘详情链接
            :param url:
            :return:
            """
            # 获取url页面的内容:bytes
            html = self.loadPage(url)
            # bytes转utf-8
            html = html.decode("utf-8")
            # 创建 Beautiful Soup 对象,指定lxml解析器
            soup = BeautifulSoup(html, "lxml")
    
            item_list = soup.select('td[class="l square"]')
            link_list = []
            for item in item_list:
                item = item.select('a')[0].attrs['href']
                link_list.append(item)
    
            return link_list
    
        def getPositionInfo(self, url):
            """
            获取我们需爬取的信息
            :param url: 招聘详情页面
            :return: None
            """
            # 获取url页面的内容:bytes
            html = self.loadPage(url)
            # bytes转utf-8
            html = html.decode("utf-8")
            # 创建 Beautiful Soup 对象,指定lxml解析器
            soup = BeautifulSoup(html, "lxml")
            # 用于存储所爬取信息的字典
            item = {}
            try:
                # 职位名称
                position_name = soup.find_all(id="sharetitle")[0].get_text()
                # 工作地点、职位类型、招聘人数
                bottomline = soup.select('tr[class="c bottomline"] td')
                # 工作地点
                working_place = bottomline[0].get_text()[5:]
                # 职位类别
                position_category = bottomline[1].get_text()[5:]
                # 招聘人数
                numbers = bottomline[2].get_text()[5:]
                # 工作职责
                operating_duty_list = soup.select('ul[class="squareli"]')[0].select('li')
                operating_duty = ""
                for duty in operating_duty_list:
                    operating_duty += duty.get_text().strip() + "
    "
                # 工作要求
                requirements_list = soup.select('ul[class="squareli"]')[1].select('li')
                requirements = ""
                for requ in requirements_list:
                    requirements += requ.get_text().strip() + "
    "
                # url链接
                url_links = url
                # 职位名称、工作地点、职位类别、招聘人数、工作职责、工作要求、url链接
                item["职位名称"] = position_name
                item["工作地点"] = working_place
                item["职位类别"] = position_category
                item["招聘人数"] = numbers
                item["工作职责"] = operating_duty
                item["工作要求"] = requirements
                item["url链接"] = url_links
            except:
                # 若异常、则舍弃这条信息
                pass
            # 保存这条记录
            if item:
                line = json.dumps(item, ensure_ascii = False) + "
    "
                self.file_name.write(line)
    
    # 主函数
    if __name__ == '__main__':
        my_spider = TencentSpider()
    
  • 相关阅读:
    中序遍历
    二叉树前序遍历
    A Real Stewart
    走遍美国 听写
    2016-12-12——2016-12-16友邻
    英语百日听力
    6.2分鱼问题两种解法
    Bootstrap组件1
    Bootstrap图标及另一个好用图标网站介绍
    Bootstrap全局CSS样式之图片
  • 原文地址:https://www.cnblogs.com/mayi0312/p/7224198.html
Copyright © 2011-2022 走看看