智联招聘 爬虫职位信息的爬取
程序员文章站
2022-03-02 23:24:35
...
1、电脑系统:ubuntu 18.04.5 LTS ;开发工具:pycharm;编译环境:anaconda3,python_vesion:Python 3.8;第三方库文件:Scrapy,selenium
2、下面就是代码了,想说的话都在注释里了
第一步:编写middlewares.py文件:
from ScrapySpider.setting import USER_AGENT_LIST,PROXIY_LIST
import base64
import random
from selenium import webdriver
from time
from scrapy.http import HtmlResponse
#开启Headers头文件,User-Agent代理池,随机选取User-Agent
class Random_UserAgent :
def process_request(self,request,spider):
User_Agent = random.choice(USER_AGENT_LIST)
request.headers['User_Agent'] = User_Agent
#开启ip代理,从ip代理池中随机选取代理IP
class Random_Proxies() :
def process_request(self,request,spider):
proxy = random.choice(PROXIY_LIST)
if 'user_password' in proxy :
bs64 = base64.b16decode(proxy['user_password'])#因为代理IP有账号密码,所以要进行编码处理
request.headers['Proxy_Authorization'] ='Basic ' +b64_up.decode('utf-8')
request.meta['Proxy'] = proxy['ip_port']
else:
request.meat['Proxy'] = proxy['ip_port']#这里Proxy不能写成小写p,会报错
#根据爬取的网页不同,选用selenium,做模拟登录或模拟点击JS
#这里只为驱动url中的js,以获取JS生成的数据
class SeleniumMiddleware():
def process_request(self,request,spider):
url = request.url
if 'scode' in url :#这里是判断想要获取的url中的数据,是否需要用到selenium
webdriver.PhantomJS()#加载无图浏览器
driver = webdriver.Chrome()#加载谷歌浏览器---谷歌浏览器需要下载驱动,放入usr/bin文件中
deiver.get(url)
time.sleep(3)
data = driver.page_source
driver.close()
res = HtmlResponse(url =url,body=data,encoding='utf-8',request =request)
return res
第二步:编写setting.py 文件
#将上面写的三个类开启
DOWNLOADER_MIDDLEWARES = {
'ScrapySpider.middlewares.SeleniumMiddleware': 544,
'ScrapySpider.middlewares.Random_Agent': 543,
'ScrapySpider.middlewares.Random_Proxy': 542
}
# Obey robots.txt rules 服从roobt.txt(遵守Robot协议的一个文件),保存在网站的服务器里,他告诉搜索爬虫引擎,网站上哪些目录下不希望被爬取收录。Ture表示遵守。
ROBOTSTXT_OBEY = False
#USER_ANGET和PROXY_LIST
USER_AGNET_LIST = [
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
]#User-Agent 网上很多
#代理池的建立可以建立在数据库中
PROXY_LIST =[
{"ip_port" : "47.104.132.34:16818"}
] #网上的一些免费ip大都不可行,这上面的ip和我电脑ip绑定了,其他电脑用不了
3、爬虫文件
class ZhaopinspiderSpider(scrapy.Spider):
name = 'zhaopinSpider'
allowed_domains = ['zhaopin.com']
start_urls = ['http://sou.zhaopin.com/?jl=749&kw=%E7%88%AC%E8%99%AB&p=1']
def start_requests(self):
url = self.start_urls[0]
# cookie 分割,变为字典形式
temp = '个人登录智联招聘的cookie,智联的cookie还是能用很长时间'
cookies = {}
for cookie in cookie_list:
list = cookie.split('=')
cookies[list[0].strip()] = list[1]
yield scrapy.Request(url=url,callback=self.parse,cookies=cookies,dont_filter=True)
def parse(self,response):
print(response.request.headers['headers'])
#打印每次请求的User-Agent
div_list = response.xpath('//*[@id="positionList-hook"]/div/div')
#职位展示页面中,想要爬取的数据部位,它的结构是一样的,可以通用
for div in div_list :
href = div.xpath('./a/@href').extract_first()
zhiwei = div.xpath('./a/div[1]/div[1]/span/@title').extract_first()
gongzi = div.xpath('./a/div[2]/div[1]/p/text()').extract_first().strip()
company = div.xpath('./a/div[1]/div[2]/span/@title').extract_first()
print('**************')
print(href,zhiwei,gongzi,company)
print(' ')
yield scrapy.Request(url=href ,callback=self.parse_datil, dont_filter=True)
def parse_datil(self,response):
#每条招聘的详细信息介绍页面,想要爬取的数据部位,结构都不一样
#下面这一堆都是为了一次性拿到数据,中间试很多错,最后只弄出来了这
#样差劲的数据出来,还要继续做数据清洗
#ps:这部分数据的提取,用xpath感觉不太好。可以试试正则,可能几条正则
#解决了,之后可以试试
print('**********')
print(response.url)
node_list = response.xpath('//*[@id="root"]/div[4]/div[1]/div[1]/div[1]')
#这上下两行不同,是因为有一个页面的数据部分,节点定位和其他不一样,开始
#我只用上面一行,会有一条连接,获取不到数据
node_list1 = response.xpath('//*[@id="root"]/div[4]/div[1]/div[1]/div[2]')
#获取节点1,div[2]标签中所有的P标签数据
pTag_list = node_list.xpath('./div[2]/p').extract()
#获取节点1,div[2]标签中所有的div标签数据
divTag_list = node_list.xpath('./div[2]/div').extract()
#获取节点2,div[2]标签中所有的div标签数据
divTag_list1 = node_list1.xpath('./div[2]/div').extract()
#获取节点1,div[2]标签的文本数据
text_list = node_list.xpath('./div[2]/text()').extract()
#上面这4种,就是我在这个页面发现出现的结构,我是问过前端开发的朋友
#为什么会出现这样非结构性的,他说是根据情况而写的,很正常,我在想,
#现在写前端也用框架了,呐,用框架写出的东西应该都是一样的吧。
if pTag_list :#判断获取的P标签是否为空
for info in pTag_list:
print(info.strip())
if divTag_list :#判断获取的div标签是否为空
for info in divTag_list:
print(info.strip())
elif text_list:#如果上面为空,则判断div[2]标签中文本为空
print(text_list)
else:
for info in divTag_list1:#如果文本都是空,那说明div[2]没有数据,应该去找另一节点
print(info)
#上面的这个解析规则,是我个人查看单个页面,写出来的。输出结果,倒是对的起写了这些东西
#个人感觉就是很不友好,不知道哪位大神,有更好的解析方式。
#后面管道和item我没有写,毕竟我只想看看结果
,