Live2D

爬虫——使用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() + "\n"
            # 工作要求
            requirements_list = soup.select('ul[class="squareli"]')[1].select('li')
            requirements = ""
            for requ in requirements_list:
                requirements += requ.get_text().strip() + "\n"
            # 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) + "\n"
            self.file_name.write(line)

# 主函数
if __name__ == '__main__':
    my_spider = TencentSpider()

 

posted @ 2017-07-23 12:09  骑着螞蟻流浪  阅读(740)  评论(0编辑  收藏  举报