前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬取51job出现can only concatenate str (not “NoneType“) to str

爬取51job出现can only concatenate str (not “NoneType“) to str

作者头像
萌萌哒的瓤瓤
发布2020-08-26 15:29:34
3.9K0
发布2020-08-26 15:29:34
举报

目录

  • 1.bug解释
  • 2.解决方案
    • 2.1添加try/except进行包裹
    • 2.2添加if/else条件判断
    • 2.3添加时直接进行类型转换
  • 3.修改完后老哥的代码

1.bug解释

一个老哥在爬取51job的信息,但是中途遇到了这个bug:

在这里插入图片描述
在这里插入图片描述

其实这个bug一眼看出来就是没有一个值可以让你来进行转换成字符串。说白了就是有一个值可能为空,但是看出来没有用,毕竟他这里面包含了6个参数,不确定到底是哪一个参数。 这时候我们就只需要打断点或者是一步一步打印变量就行了,这里我选择的是将老哥的方法进行改写,他选择的是直接将所有的变量一次性全部传给一个对象,我选择的是一个一个传,对比一下,大家就知道了。 老哥的方法:

在这里插入图片描述
在这里插入图片描述

我的方法;

在这里插入图片描述
在这里插入图片描述

之后我们来对比一下我们输出的结果 老哥结果:

在这里插入图片描述
在这里插入图片描述

我的结果;

在这里插入图片描述
在这里插入图片描述

我们点进网页进去看一下发现:

在这里插入图片描述
在这里插入图片描述

发现整个网页上就没有出现薪资的信息 大家可以对比一下就知道了,显然就是在薪资出现None的时候老哥的代码就报错了。这是为啥呢? 接下来给大家讲解一下。 python中的数组和Java中的列表是不一样的。 Java的数组一旦规定了列表类型就不能再添加不同类型的元素进入数组,就好比我定义了整形的列表就不能再添加字符串对象进入该列表 python就不同了,python定义的列表是可以包含不同元素的,就比方说下面这个例子:

代码语言:javascript
复制
list1 = ['physics', 'chemistry', 1997, 2000]

所以老哥添加列表元素的时候已经规定好了我的元素是字符串,这是没有问题的,但是当money为None的时候就尴尬了,我们要知道这里的None并不是代表值为None,而是直接代表类型为None,所以这里很明显他是不能自己转换成String的。 但是我的就不一样了,我是一个一个添加的,所以列表本身也不知道你添加的数据是什么类型的,所以他都会给你存储进来。不管你是什么类型的,就算你没有类型他也会帮你存进来。 所以我的数据没有报错。

2.解决方案

2.1添加try/except进行包裹

代码语言:javascript
复制
 try:
        data.append(jobpage+"  "+jname+"  "+money+"  "+gname+"  "+jinyan+"  "+xuli)
    except:
        pass

运行效果:成功跑完

在这里插入图片描述
在这里插入图片描述

2.2添加if/else条件判断

代码语言:javascript
复制
    if str(moneys[0])=="<strong></strong>":
        money="面谈"
    else:
        money = moneys[0].string

运行效果:成功跑完

在这里插入图片描述
在这里插入图片描述

2.3添加时直接进行类型转换

代码语言:javascript
复制
data.append(jobpage+"  "+jname+"  "+str(money)+"  "+gname+"  "+jinyan+"  "+xuli)

运行效果:

在这里插入图片描述
在这里插入图片描述

3.修改完后老哥的代码

代码语言:javascript
复制
from bs4 import BeautifulSoup
# 正则表达式
import re
# 定制url,获取网页数据
import urllib.request,urllib.error
# 进行excel操作
import xlwt
# 进行数据库操作
import sqlite3
# 根据需求对输入的解析
from urllib import parse
from lxml import etree
import json
import requests



keyWord =input("请输入需要爬取的关键字:")
word=parse.quote(keyWord)
newWord = parse.quote(word)
# jobData={}#每一个记录是一个列表,把二次获取到的网页存成字典格式
# jobList =[]  #把上面获取到的信息放在列表中


def main():
    # 爬取网页
    # url = "https://search.51job.com/list/090200,000000,0000,00,9,99," + newWord + ",2," + str(pageNmb) + ".html"

    # html = askUrl(url)
    # print(html)
    datalist = []
    for i in range(1,2):
        url = "https://search.51job.com/list/090200,000000,0000,00,9,99,"+newWord+",2,"+str(i)+".html"
        pagaLink=getLink(url)            #爬取列表页,获取该列表的全部岗位链接
        if len(pagaLink) == 0:
            break
        for jobpage in pagaLink:
            data=getaData(jobpage)           #一个详情页的链接
            datalist.append(data)
        print(datalist)

    # datalist = getaData(baseurl)
    # savapath = ".\\豆瓣电影251.xlsx"
    # dbpath = "movie.db"
    # 保存数据到excel
    # savaData(datalist,savapath)
    # 保存数据到数据库
    # savaData2DB(datalist, dbpath)

# 获取网页信息
def getLink(url):
    dataList=[]
    #获取到源码
    html = askUrl(url)
    data = str(html)
    # print(data)
    find_info = re.findall(r'window.__SEARCH_RESULT__ = {(.*?)keywords', data)
    # print(find_info)
    #拼接上少了的:keywords":"找工作,求职,人才,招聘"}这一部分
    find_info = '{' + str(find_info[0]) + 'keywords":"找工作,求职,人才,招聘"}'
    # print(find_info)
    #  将获取到内容转换为json格式
    json_data = json.loads(find_info)
    # print(json_data)
    for i in json_data['engine_search_result']:
        dataList.append(i['job_href'])
    # print(jobList)
    # print(dataList)
    return dataList


# 二次获取到的链接页面解析
def getaData(jobpage):
    data = []
    jobHtml = askUrl(jobpage) #获取详情页面
    # print(jobHtml)
    soup = BeautifulSoup(jobHtml, "html.parser")

    # data.append(jobpage)
    jnames = soup.select('h1[title]')#职位名称
    # print(jnames)
    jname = jnames[0]["title"]
    # print(jname)
    # data.append(jname)

    moneys = soup.select("div.cn strong ")  # 待遇
    # print(moneys[0])
    if str(moneys[0])=="<strong></strong>":
        money="面谈"
    else:
        money = moneys[0].string
    # data.append(money)

    gnames = soup.select(".cname > a")  # 公司名字
    gname = gnames[0]["title"]
    # data.append(gname)

    jobMlsit = soup.select("p.msg")  # 工作经验
    list1 = jobMlsit[0]["title"].split("|")
    jinyan = list1[1].strip()
    # data.append(jinyan)

    xuli = list1[2].strip()  # 学历
    # data.append(xuli)
    # print(xuli)
    # renshu = list1[3].strip()  # 招人数
    # try:
    data.append(jobpage+"  "+jname+"  "+money+"  "+gname+"  "+jinyan+"  "+xuli)
    # except:
    #     pass
        # print(renshu)
    print(data)
    return data


# 爬取网页
def askUrl(url):
    # 模拟浏览器信息,想豆瓣服务器发送信息
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
    }
    # 用户代理,告诉服务器,我们是什么类型的机器,浏览器(本质上是告诉浏览器我们可以接收什么水平的内容)

    # 发送请求消息
    request = urllib.request.Request(url,headers=headers)
    html = ""
    # 捕获异常
    try:
        # 取得响应
       response = urllib.request.urlopen(request)
        # 获取网页内容
       html = response.read().decode("gbk")
       # print(html)
    except urllib.error.URLError as e:
       if hasattr(e,"code"):
           print(e.code)
       if hasattr(e,"reson"):
           print(e.reson)
    return html


if __name__ == '__main__':
    main()
    # askUrl("https://jobs.51job.com/chengdu-gxq/124561448.html?s=01&t=0")
    print("爬取完毕")
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1.bug解释
  • 2.解决方案
    • 2.1添加try/except进行包裹
      • 2.2添加if/else条件判断
        • 2.3添加时直接进行类型转换
        • 3.修改完后老哥的代码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档