手把手教你,Python爬取招聘信息。一学就会,一写就废。

零基础的同学也能上手的,简单详细的python爬虫教学,也是经验的分享。

话不多说我们直接进入主题。

本次用到的python爬虫第三方库。

  1. requests:不是内置的,所以需要手动安装 => pip install requests
  2. re (正则表达式):用于requests爬取数据后进行解析,也是需要手动安装,==> pip install re 。
  3. Json :是一种轻量级的数据交换格式,易于人阅读和编写。

注意:(1)、因返回的数据较多,这里就不给予展示了。

           (2)、代码是一段一段的,进行一步一步的讲解,最后会附上所有的源码。


一、爬虫数据思路

1.进入网址

        网站连接可在代码中的 url 复制 ,因为某些不可说的原因。

       输入python ,查找python招聘信息。

2.查看需要的数据在源码中的位置,判断是否为动态网页。

python爬取数据导入mongo python爬取数据案例_python

 在源码里面进行搜索“python开发工程师”,找到其对应的位置。

python爬取数据导入mongo python爬取数据案例_3D_02

 在body标签中没有对应的数据,而在script中发现了数据所在。此时说明此网页是一个动态网页。可以利用re(正则表达式)来解析所需要数据。

二、代码

        1.首先导入 requests 和 re模块

                import requests

                import re

                import json

        2.利用 requests 进行数据请求,此段代码有响应数据,这可以用此段代码。如果无数据或者乱码则用下面的代码。

import requests
import re
import json

#长类型字符串可以用 () 进行连接
'''
https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=
'''

url = ('https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html?'
   'lang=c&postchannel=0000&workyear=99&cotype=99&
degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=')

resp = requests.get(url).text  # .text 是属性,让返回的数据为文本格式 

print(resp)
'''
    如果有数据响应,并且和源码一样说明请求没问题,如果请求的是一串乱码或者没有数据。
    可以加上 请求头(User-Agent) 和 Cookie
'''

 Cookie的位置

python爬取数据导入mongo python爬取数据案例_python_03

 请求头(User-Agent)的位置

python爬取数据导入mongo python爬取数据案例_数据_04

url = ('https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,1.html?'
       'lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=')

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44",
    "Cookie":"_uab_collina=165034940878617547028482; guid=22aac7caed33de3e1aa0a7e4c0d1cb66; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; slife=lowbrowser%3Dnot%26%7C%26; search=jobarea%7E%60000000%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch1%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%C5%C0%B3%E6%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch2%7E%60190200%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%C5%C0%B3%E6%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch3%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA12%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAweb%C7%B0%B6%CB%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch4%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA01%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAweb%C7%B0%B6%CB%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; partner=sem_pc360s1_29369; adv=ad_logid_url%3Dhttps%253A%252F%252Ftrace.51job.com%252Ftrace.php%253Fpartner%253Dsem_pc360s1_29369%2526ajp%253DaHR0cHM6Ly9ta3QuNTFqb2IuY29tL3RnL3NlbS9MUF8yMDIwXzEuaHRtbD9mcm9tPTM2MGFk%2526k%253D7d16490a53bc7f778963fbe04432456c%2526qhclickid%253Df5b179a19bec32c2%26%7C%26; acw_tc=76b20fee16504209993903119e78ac362eecffeaff8962fd8993f709e597a3; privacy=1650421060; acw_sc__v3=625f6d92716e3fa06b52c98c241a87f1989d43fe; ssxmod_itna=Yq+xyDnmDtYQqY5GHY+mDjxWqDKWh0oODr8Gu2g4GN4=oDZDiqAPGhDCb+KOhumuGtdQjfw3Ht0j8xKe6nACa+pCFZLeGLDmKDyCQiR4oD445GwD0eG+DD4DWDmWHDnxAQDjxGp9uXwV=Dm4GW8qGfDDoDYf6uDitD4qDBmOdDKqGg8qq5BA=PyRrMjmt5WmD48qDM0eGXnAaNpna7gGNP=PcxHgQDzLHDtqNMSLddx0PBldXx=gobmBvxKTwFCGGPGDxWC+4HK0GxYrqQDf5Q0AoY/24jXY8DG+Dtj0GdKiD===; ssxmod_itna2=Yq+xyDnmDtYQqY5GHY+mDjxWqDKWh0oODr8Gu2xA=ceD/0BQDFxruOtwk7hyp7KvOKC=7KGFD4E70hVi8QuTheBQ1KKIov6B8HG4V9WCBLmQwGotE8IOmYIOBF9K5r4DwwVy+CDMtGrv0ar2=BbqI2QY3Y4gmKoUEHH21WPW2hKinpi4gGdohurZpFba9HHh+mwEbikFb7bKxkLDxdrw+nsG8Lr6t9TkxAUe/SU+UL2d/TvtrGw46exiDpTqWgCGtGAtBAqxSbuszmKGaqA8iTOmL/Rmq6TFKHnG34b9E6w5gL99R3Xa+soEHULN5xs5hK4q1eda3QkkrYB4O2RYLTW4nCBbs3Ez=eWCQFSM=QlG2++E8z2RGVdo4OsUqNaqHe7Fim80QaKeh3kokxIB8F1Q+vlwIl+ekN5oG2f3umHSurO2WYE=6fbFPGLfE7dIr6EXe+QZO8dEFgARODpPIPYCedAwrPD7Q5lQPnP5ip5QwnhwS+GMS+S/YCnyhY=h0qfEhx6DKTml+pNBKtAvL2xNmpxwhos4ZYqIaqY7AYqx=ZqGGDYiw6Oe=AxDjKDeu3CAICKcMYdU8Dyiqg9D7A3hded7cM9ayxNN7xFgDCD4L/t7D4q0nhuxKyD8Y=BODKiDD==="
}

resp = requests.get(url,headers=headers).text

print(resp)

         3.利用 re 正则解析 script 中的数据,并进行数据清洗

                        re.findall(pattern,string,flags=0) :返回string中所有与pattern匹配的全部字符串,返回形式为数组。

                        re.S:如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。

r = re.findall('window.__SEARCH_RESULT__ = (.*?)</script>',resp,re.S)
r_string = ''.join(r) # 去掉空白内容
print(r_string)

r_dic=json.loads(r_string) #转换成字典格式
print(r_dic)
print(r_dic["engine_jds"]) #获取的是数组格式的数据
print(r_dic["engine_jds"][0]["job_name"]) #获取岗位名称

 print(r_dic)的返回结果

python爬取数据导入mongo python爬取数据案例_数据_05

print(r_dic["engine_jds"]) 的返回结果

python爬取数据导入mongo python爬取数据案例_python_06

 print(r_dic["engine_jds"][0]["job_name"]) 的返回结果

python爬取数据导入mongo python爬取数据案例_python爬取数据导入mongo_07

        4.遍历获取数据

                 此时能获取到具体的数据,距离成功也就越来越近了。我抓取的数据是一页的数据,但是一页中有很多的岗位信息,所以我们要进行遍历,获取每一个岗位的具体信息。

for r_index in r_dic["engine_jds"]:
    print(r_index["company_name"]) #公司名称
    print(r_index["companytype_text"]) #企业类别
    print(r_index["job_name"]) #岗位名称
    print(r_index["providesalary_text"]) #岗位薪水jobwelf
    print(r_index["jobwelf"]) #岗位福利
    print(r_index["attribute_text"]) #岗位地区和岗位要求
    
    break
#遍历一次看看信息是否正确

python爬取数据导入mongo python爬取数据案例_数据_08

        5.保存本地文件

        注意:用 open("path","a") ,a  的方式进行存储时,如果文件存在就会报错。这里我只进行了一次存储后就 break 掉了,所以只有一条数据。要进行多次存储去掉break就行。

for r_index in r_dic["engine_jds"]:
    company_name=r_index["company_name"] #公司名称
    companytype_text=r_index["companytype_text"] #企业类别
    job_name=r_index["job_name"] #岗位名称
    providesalary_text=r_index["providesalary_text"]#岗位薪水jobwelf
    jobwelf=r_index["jobwelf"] #岗位福利
    attribute_text=r_index["attribute_text"]#岗位地区和岗位要求

    f = open("csdn_51job.csv",'a') # 用 a(追加) 的方式 进行数据存储
    f.write(f"{company_name},{companytype_text},{job_name},{providesalary_text},{jobwelf},{','.join(attribute_text)}") #把获取到的数据写入文件
    f.close() #最好一定要记住关闭文件
    break

 csdn_51job.csv 文件内容如下:

python爬取数据导入mongo python爬取数据案例_python爬取数据导入mongo_09

         6.最后进行多次多页爬取数据。

                 (1). 思路

                                设置的页数,在url肯定是有规律的,所以观察两个 url 的区别即可。

python爬取数据导入mongo python爬取数据案例_3D_10

                                 知道差别后进行 for 循环遍历即可。

三、最后附上完整的代码 ,这里我只爬取了一页数据,还是一样,想要多页去掉break即可

import json
import requests
import re


for pageindex in range(1,500): #多页数爬取
    print(f'第{pageindex}页开始')
    #进行请求url
    url = (f'https://search.51job.com/list/000000,000000,0000,00,9,99,python,2,{pageindex}.html?'
           'lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=')
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44",
        "Cookie":"_uab_collina=165034940878617547028482; guid=22aac7caed33de3e1aa0a7e4c0d1cb66; nsearch=jobarea%3D%26%7C%26ord_field%3D%26%7C%26recentSearch0%3D%26%7C%26recentSearch1%3D%26%7C%26recentSearch2%3D%26%7C%26recentSearch3%3D%26%7C%26recentSearch4%3D%26%7C%26collapse_expansion%3D; slife=lowbrowser%3Dnot%26%7C%26; search=jobarea%7E%60000000%7C%21ord_field%7E%600%7C%21recentSearch0%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch1%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%C5%C0%B3%E6%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch2%7E%60190200%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FApython%C5%C0%B3%E6%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch3%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA12%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAweb%C7%B0%B6%CB%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21recentSearch4%7E%60000000%A1%FB%A1%FA000000%A1%FB%A1%FA0000%A1%FB%A1%FA00%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA99%A1%FB%A1%FA99%A1%FB%A1%FA01%A1%FB%A1%FA99%A1%FB%A1%FA9%A1%FB%A1%FA99%A1%FB%A1%FA%A1%FB%A1%FA0%A1%FB%A1%FAweb%C7%B0%B6%CB%A1%FB%A1%FA2%A1%FB%A1%FA1%7C%21; partner=sem_pc360s1_29369; adv=ad_logid_url%3Dhttps%253A%252F%252Ftrace.51job.com%252Ftrace.php%253Fpartner%253Dsem_pc360s1_29369%2526ajp%253DaHR0cHM6Ly9ta3QuNTFqb2IuY29tL3RnL3NlbS9MUF8yMDIwXzEuaHRtbD9mcm9tPTM2MGFk%2526k%253D7d16490a53bc7f778963fbe04432456c%2526qhclickid%253Df5b179a19bec32c2%26%7C%26; acw_tc=76b20fee16504209993903119e78ac362eecffeaff8962fd8993f709e597a3; privacy=1650421060; acw_sc__v3=625f6d92716e3fa06b52c98c241a87f1989d43fe; ssxmod_itna=Yq+xyDnmDtYQqY5GHY+mDjxWqDKWh0oODr8Gu2g4GN4=oDZDiqAPGhDCb+KOhumuGtdQjfw3Ht0j8xKe6nACa+pCFZLeGLDmKDyCQiR4oD445GwD0eG+DD4DWDmWHDnxAQDjxGp9uXwV=Dm4GW8qGfDDoDYf6uDitD4qDBmOdDKqGg8qq5BA=PyRrMjmt5WmD48qDM0eGXnAaNpna7gGNP=PcxHgQDzLHDtqNMSLddx0PBldXx=gobmBvxKTwFCGGPGDxWC+4HK0GxYrqQDf5Q0AoY/24jXY8DG+Dtj0GdKiD===; ssxmod_itna2=Yq+xyDnmDtYQqY5GHY+mDjxWqDKWh0oODr8Gu2xA=ceD/0BQDFxruOtwk7hyp7KvOKC=7KGFD4E70hVi8QuTheBQ1KKIov6B8HG4V9WCBLmQwGotE8IOmYIOBF9K5r4DwwVy+CDMtGrv0ar2=BbqI2QY3Y4gmKoUEHH21WPW2hKinpi4gGdohurZpFba9HHh+mwEbikFb7bKxkLDxdrw+nsG8Lr6t9TkxAUe/SU+UL2d/TvtrGw46exiDpTqWgCGtGAtBAqxSbuszmKGaqA8iTOmL/Rmq6TFKHnG34b9E6w5gL99R3Xa+soEHULN5xs5hK4q1eda3QkkrYB4O2RYLTW4nCBbs3Ez=eWCQFSM=QlG2++E8z2RGVdo4OsUqNaqHe7Fim80QaKeh3kokxIB8F1Q+vlwIl+ekN5oG2f3umHSurO2WYE=6fbFPGLfE7dIr6EXe+QZO8dEFgARODpPIPYCedAwrPD7Q5lQPnP5ip5QwnhwS+GMS+S/YCnyhY=h0qfEhx6DKTml+pNBKtAvL2xNmpxwhos4ZYqIaqY7AYqx=ZqGGDYiw6Oe=AxDjKDeu3CAICKcMYdU8Dyiqg9D7A3hded7cM9ayxNN7xFgDCD4L/t7D4q0nhuxKyD8Y=BODKiDD==="
    }
    resp = requests.get(url,headers=headers).text

    #用re进行数据解析
    r = re.findall('window.__SEARCH_RESULT__ = (.*?)</script>',resp,re.S)
    r_string = ''.join(r)
    r_dic=json.loads(r_string) #转换成字典格式

    #遍历每一页的数据
    for r_index in r_dic["engine_jds"]:
        company_name=r_index["company_name"] #公司名称
        companytype_text=r_index["companytype_text"] #企业类别
        job_name=r_index["job_name"] #岗位名称
        providesalary_text=r_index["providesalary_text"]#岗位薪水jobwelf
        jobwelf=r_index["jobwelf"] #岗位福利
        attribute_text=r_index["attribute_text"]#岗位地区和岗位要求

        #存储所解析的数据到 csdn_51job.csv 文件中
        f = open("csdn_51job.csv",'a') # 用 a(追加) 的方式 进行数据存储 ,前提:csdn_51job.csv文件必须由系统创建
        f.write(f"{company_name},{companytype_text},{job_name},{providesalary_text},{jobwelf},{','.join(attribute_text)}\n") #把获取到的数据写入文件
        f.close() #最好一定要记住关闭文件

    print(f'第{pageindex}页结束')
    break

 

这段代码存在一个BUG,也就是网站的一个反爬机制,人机验证的一个拖拽验证。

所以会报错
r_string = ''.join(r)
r_dic=json.loads(r_string)
这段代码会报一个这个错误: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
究其原因也就是 r_string 会返回一个空列表,json.loads() 方法就报错了。
其实也不是什么大问题。代码用肯定是能用的,过个把小时就能用了。

解决办法:解决滑块验证的问题