Python 爬虫之初体验(实习僧)

1,023 阅读7分钟

你好,我是悦创。

我们前面入手的第一篇是糗事百科,这里就不细讲了,部分代码提供如下:

为爬取的笑话加序号:两种方法:

方法一:

在这里插入图片描述

方法二更加优雅和更加Python:

在这里插入图片描述

扩展:

筛选非空内容:

在这里插入图片描述 好,咱们进入正题!

一: 简单的请求(实习僧)

import requests
from bs4 import BeautifulSoup

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
url = 'https://www.shixiseng.com/'
# https://www.shixiseng.com/interns/?page=1&keyword=Python&city=%E5%8C%97%E4%BA%AC
for page in range(1,3):
	req = requests.get(url + f'interns/?page={page}&keyword=Python&city=%E5%8C%97%E4%BA%AC', headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	print(soup.prettify())

一:抓取职位信息

  1. 分析(实习僧) 在这里插入图片描述

① 自己定义了一个字体:MyFont;

② 然后,通过编码格式、前端的js交互来展示到页面上;

③ 不因约定俗成的字体编码方式;

④ div.intern-wrap 选取形式

offers = soup.select('div.intern-wrap')  # 得到的数据是list

⑤ 选取职位名称:

在这里插入图片描述

title = offer.select('a.title')[0].text

⑥ 选取薪资: 在这里插入图片描述

salary = offer.select('div.f-l p span.day')[0].text
截至目前的完整代码
import requests
from bs4 import BeautifulSoup

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
url = 'https://www.shixiseng.com/'
# https://www.shixiseng.com/interns/?page=1&keyword=Python&city=%E5%8C%97%E4%BA%AC
for page in range(1,2):
	req = requests.get(url + f'interns/?page={page}&keyword=Python&city=%E5%8C%97%E4%BA%AC', headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	# print(soup.prettify())
	offers = soup.select('div.intern-wrap')  # 得到的数据是list
	# print(offers)
	for index, offer in enumerate(offers):
		# 爬取单独的一个职位信息,自动解决全部
		title = offer.select('a.title')[0].text
		salary = offer.select('div.f-l p span.day')[0].text
		print(f'{index}title:>{title}, salary:>{salary}')

运行结果:

空白(不能说空白吧,有爬取到,只不过在上面的控制台里面我们可以理解为空白)部分就是实习僧的反爬虫机制;接下来就来破解它!

二: 获取编码方式

  1. 字体有3000多个,我们分析运行结果可知,实习僧网站就设置了一些常用字体的编码方式,这样我们计算机并没有这些字体编码方式;而相对比之下:我们发现对应的薪资是一个都没有显示出来,毕竟薪资也就才由几个基本数字组合而成的:0、1、2、3、4、5、6、7、8、9

  2. 接下来关键词函数:encode()

  3. 在enconde()里面添加utf-8

  4. encode('utf-8')

    代码示例:

    print(salary.encode('utf-8'))
    

    输出结果:

我们用encode的目的就是把salary获得到的数据解码成16进制,分析其中规律。

转换成16进制的utf-8的形式

分析该获得的16进制:

b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xee\x84\x97\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\xbd\xa6\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\x98\x9a\xee\x98\x9a-\xee\xbb\xa0\xee\xb3\xaf\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\xbd\xa6\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\x84\x97\xee\x98\x9a\xee\x98\x9a-\xef\x9b\xa0\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xef\x9b\xa0\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\x84\x97\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\xbd\xa6\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\x98\x9a\xee\x98\x9a-\xee\xb3\xaf\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'
b'\xee\xbb\xa0\xee\xbd\xa6\xee\x98\x9a-\xee\x84\x97\xee\x98\x9a\xee\x98\x9a/\xe5\xa4\xa9'


分析我们会发现:150是三个数字,而获取到的16进制有9个,那9÷3 = 3,我们就可以得到每三个组成一个数字;

那就可以得出:(这里得到的数据,并不能直接使用,因为实习僧使用的动态加密的。一段时间,这些得到的数据都会改变。

​	· 数字0对应 --->  \xee\x98\x9a

​	· 数字1对应 --->  \xee\xbb\xa0

​	· 数字2对应 --->  \xee\xb3\xaf

​	· 数字3对应 --->  \xee\x84\x97

​	· 数字4对应 --->  \xef\x9b\xa0

​	· 数字5对应 --->  \xee\xbd\xa6

​	· 数字6对应 --->  略

​	· 数字7对应 --->  略

​	· 数字8对应 --->  略

​	·  数字9对应 --->  略

普及:

\x >>>16进制

0、1>>>2进制
# ============================
# -*8 coding: utf-8 -*-
# @Author:   黄家宝
# @Corporation: AI悦创
# @Version:  1.0 
# @Function: 简单爬取
# @DateTime: 2019-07-24 18:49:36
# ============================
import requests
from bs4 import BeautifulSoup

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
url = 'https://www.shixiseng.com/'
# https://www.shixiseng.com/interns/?page=1&keyword=Python&city=%E5%8C%97%E4%BA%AC
for page in range(1,3):
	req = requests.get(url + f'interns/?page={page}&keyword=Python&city=%E5%8C%97%E4%BA%AC', headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	# print(soup.prettify())
	offers = soup.select('div.intern-wrap')  # 得到的数据是list
	# print(offers)
	for index, offer in enumerate(offers):
		# 爬取单独的一个职位信息,自动解决全部
		title = offer.select('a.title')[0].text
		salary = offer.select('div.f-l p span.day')[0].text.encode('utf-8')
		# print(f'{index}title:>{title}, salary:>{salary}')
		salary = salary.replace(b'\xee\x98\x9a', b'0')
		salary = salary.replace(b'\xee\xbb\xa0', b'1')
		salary = salary.replace(b'\xee\xbb\xa0', b'2')
		salary = salary.replace(b'\xee\x84\x97', b'3')
		salary = salary.replace(b'\xef\x9b\xa0', b'4')
		salary = salary.replace(b' \xee\xbd\xa6', b'5')
		a = salary.decode('utf-8')
		print(f'{index}title:>{title}, salary:>{a}')

注意:

​ · 我们在用encode编码之后还要用decode解码回去,而且如果encode里面用的是:utf-8,那decode里面也要用utf-8,同理:用的是gbk,我们decode也用gbk

​ · utf-8还可以这样写:utf8、utf_?

​ · 获取文字(文本):

  1. text()
  2. string()
  3. strings()
  4. stripped_strings()
  5. strip()

·replace()作用对象>>>字符串,是新建一个,而不是在本身创建;

代码示例:

# 注意观察
l = [1, 2, 3]
for i in l:
    i = str(i)
    i.replace('1', '100')
    print(i)

# 注意对比

l = [1, 2, 3]
for i in l:
    i = str(i)
    a = i.replace('1', '100')
    print(a)

扩展:爬取每个职位信息的详情(小小的深度爬取)

Ps:有问题公众号后台直接留言哦!skrskrskr~

或者去我的知识星球:

t.zsxq.com/fAqjYvb

图例 :

在这里插入图片描述

分析:

在这里插入图片描述

对应代码:
import requests
from bs4 import BeautifulSoup

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
url = 'https://www.shixiseng.com/'

for index, page in enumerate(range(1,2)):
	req = requests.get(url + f'interns/?page={page}&keyword=Python&city=%E5%8C%97%E4%BA%AC', headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	offers = soup.select('.f-l.intern-detail__job a')
	print(offers)


输出结果观察

在这里插入图片描述

所以用get的方法获取:

for item in offers:
		print(item.get('href'))

输出结果:

在这里插入图片描述


而且基本操作类似 >>> 那我们就可以把这个过程或者说请求写成一个函数detail_page:

首先,分析新页面:

在这里插入图片描述

切换另一个详情页看看:

在这里插入图片描述 所以,可想而知:

一言不合就扔代码:

def detail_page(new_url):
	req = requests.get(new_url, headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	job_name = soup.select('.new_job_name')
    print(job_name)

在这里插入图片描述

下一步就是:只要标题!!!

分析:上面结果可以看见,数据类型是一个个列表,然后需要获取文字:

有好多方法这里咱们来写一下:

def detail_page(new_url):
	req = requests.get(new_url, headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	job_name = soup.select('.new_job_name')[0].text
	print(job_name)

输出结果:

在这里插入图片描述 截至目前的完整代码:

# ============================
# -*8 coding: utf-8 -*-
# @Author:   黄家宝
# @Corporation: AI悦创
# @Version:  1.0 
# @Function: 功能
# @DateTime: 2019-07-24 18:49:36
# ============================
import requests
from bs4 import BeautifulSoup

header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
url = 'https://www.shixiseng.com/'

def detail_page(new_url):
	req = requests.get(new_url, headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	job_name = soup.select('.new_job_name')[0].text
	print(job_name)

for index, page in enumerate(range(1,2)):
	req = requests.get(url + f'interns/?page={page}&keyword=Python&city=%E5%8C%97%E4%BA%AC', headers = header)
	soup = BeautifulSoup(req.text, 'lxml')
	offers = soup.select('.f-l.intern-detail__job a')
	# print(offers)
	for index, item in enumerate(offers):
		print(item)
		new_url = item.get('href')    # 这个获取到的就是字符串,不信可以用内置函数type检测一下下
		detail_page(new_url)

那其他的都一样了,就不一一来写和分析咯! 我公众号原文: 公众号原文 我是AI悦创,依然不会定时给你们分享一些有趣好玩实用的东西,欢迎关注~


警察蜀黍!就是这个人!脑子简直有泡!还不赶紧关注一下!

img

在这里插入图片描述