无锡网站 app,域名申请成功后怎么做网站,用织梦做网站,做高仿包的网站有哪些在本篇博客中#xff0c;我们将介绍如何使用 Scrapy 框架结合 JS 逆向技术、代理服务器和自定义中间件#xff0c;来爬取猎聘网站的招聘数据。猎聘是一个国内知名的招聘平台#xff0c;提供了大量的企业招聘信息和职位信息。本项目的目标是抓取指定城市的招聘信息#xff0…在本篇博客中我们将介绍如何使用 Scrapy 框架结合 JS 逆向技术、代理服务器和自定义中间件来爬取猎聘网站的招聘数据。猎聘是一个国内知名的招聘平台提供了大量的企业招聘信息和职位信息。本项目的目标是抓取指定城市的招聘信息提取相关的职位名称、薪资、公司名称等信息。
项目结构
项目的基本结构如下
liepin/
├── liepin/
│ ├── items.py # 定义Item模型
│ ├── pipelines.py # 定义数据处理管道
│ ├── settings.py # Scrapy的配置文件
│ ├── spiders/
│ │ └── lp_spider.py # 爬虫代码
├── lp.js # JS逆向代码
└── data.csv # 存储爬取的招聘数据lp_spider.py定义了爬虫的核心逻辑负责发起请求、解析数据并将数据传递给 pipeline 进行处理。middlewares.py自定义了爬虫和下载器中间件处理请求的重试逻辑和代理。pipelines.py定义了数据存储的逻辑将爬取的数据保存为 CSV 文件。settings.py配置 Scrapy 框架的各项设置。lp.js包含 JS 代码用于生成请求所需的参数。
步骤 1: 配置代理和用户身份认证
在爬虫开始前我们首先需要配置代理服务器。为了防止 IP 被封锁我们使用了快代理提供的代理服务器。代理认证信息包括 username 和 password通过将这些信息构造为代理 URL
# 隧道域名:端口号
tunnel xxxx# 用户名密码方式
username xxxx
password xxxxproxy_url fhttp://{username}:{password}{tunnel}然后我们将在后续请求中使用该代理 URL。
步骤 2: 使用 JS 逆向技术生成请求参数
猎聘的 API 请求需要一个动态生成的 ckId 参数这是通过执行 JavaScript 代码来生成的。为了获取这个参数我们通过 Python 的 execjs 库来执行 JS 代码。
js_file open(../lp.js, moder, encodingutf-8).read()
js_code execjs.compile(js_file)
ckId js_code.call(r, 32)其中r 是 JS 代码中的一个函数用于生成一个随机的 ckId 值。这样可以模拟正常用户请求避免被反爬虫机制拦截。
步骤 3: 编写爬虫逻辑
爬虫的核心是发起请求并解析返回的数据。我们定义了一个名为 LpSpider 的爬虫类继承自 Scrapy 的 Spider 类。
class LpSpider(scrapy.Spider):name lpcustom_settings {RETRY_ENABLED: True,RETRY_TIMES: 3,RETRY_HTTP_CODES: []}def start_requests(self):for city in city_list:for key in key_word:for page in range(0, 10):js_code execjs.compile(js_file)ckId js_code.call(r, 32)data { ... } # 构造请求数据json_data json.dumps(data)url https://api-c.liepin.com/api/com.liepin.searchfront4c.pc-search-jobheaders { ... } # 请求头部信息yield scrapy.Request(urlurl, methodPOST, headersheaders, bodyjson_data, callbackself.parse, meta{proxy: proxy_url})步骤 4: 解析响应数据
当服务器返回职位数据时我们需要提取相关信息。主要的数据包括职位名称、薪资、公司信息等。在 parse 方法中我们从 JSON 响应中提取数据并将每个职位的详情链接传递给 parse_details_page 方法。
def parse(self, response):data json.loads(response.body)job_card_list data[data][data][jobCardList]for job_card in job_card_list:job_link job_card[job][link]yield scrapy.Request(urljob_link, callbackself.parse_details_page, meta{proxy: proxy_url})步骤 5: 解析职位详情页
在职位详情页中我们进一步提取职位的详细信息如公司介绍、职位描述等。
def parse_details_page(self, response):try:item LiepinItem()item[title] response.xpath(//span[classname ellipsis-2]/text()).get()item[salary] response.xpath(//span[classsalary]/text()).get()item[company_name] response.xpath(//div[classname ellipsis-1]/text()).get()item[company_intro] response.xpath(//div[classinner ellipsis-3]/text()).get()item[job_intro] response.xpath(//dd[data-selectorjob-intro-content]/text()).get()item[job_loca] response.xpath(/html/body/section[3]/div[1]/div[3]/span[1]/text()).get()item[job_exp] response.xpath(/html/body/section[3]/div[1]/div[3]/span[3]/text()).get()item[job_educate] response.xpath(/html/body/section[3]/div[1]/div[3]/span[5]/text()).get()key_word_elements response.xpath(//div[classtag-box]/ul/li/text())item[key_word_list] [kw.get() for kw in key_word_elements]item[company_info] [response.xpath(//div[classcompany-other]/div[1]/span[classtext]/text()).get(),response.xpath(//div[classcompany-other]/div[2]/span[classtext]/text()).get(),response.xpath(//div[classcompany-other]/div[3]/span[classtext]/text()).get(),]item[details_url] response.urlyield itemexcept Exception as e:self.logger.error(fAn error occurred: {e})步骤 6: 配置重试和延迟
由于爬虫在运行时可能会遇到网络错误或被目标网站屏蔽因此我们需要实现请求的重试逻辑。我们通过自定义重试中间件来实现该功能。
class CustomRetryMiddleware(RetryMiddleware):def process_exception(self, request, exception, spider):if isinstance(exception, self.EXCEPTIONS_TO_RETRY):retry_times request.meta.get(retry_times, 0) 1if retry_times self.max_retry_times:retryreq self._retry(request, exception, spider)if retryreq is not None:retryreq.meta[retry_times] retry_timesreturn retryreq步骤 7: 数据存储
抓取到的职位信息通过 Scrapy 的 pipeline 存储到 CSV 文件中。我们定义了一个 LiepinPipeline 类来处理数据存储。
class LiepinPipeline:def __init__(self):self.file open(data.csv, a, newline, encodingutf-8)self.writer csv.writer(self.file)self.writer.writerow([Job Name, Salary, Company Name, Company Intro, Job Intro, Job Location, Job Experience, Job Education, Key Word List, Company Info, Details URL])def process_item(self, item, spider):self.writer.writerow([item[title], item[salary], item[company_name], item[company_intro], item[job_intro], item[job_loca], item[job_exp], item[job_educate], item[key_word_list], item[company_info], item[details_url]])return itemdef close_spider(self, spider):self.file.close()将爬取失败的代码采用selenium进行重采登录后
代码的主要流程如下 读取失败的请求URL 我们从一个文件failed_requests.txt中读取之前失败的URL并存储在failed_requests列表中。 配置Selenium WebDriver 我们使用Chrome浏览器作为Selenium的驱动程序通过webdriver.Chrome()初始化浏览器实例。设置隐式等待时间implicitly_wait(3)来处理网页加载的延迟。 处理每个失败的请求 对于每个失败的URL我们重新访问该页面。为了避免频繁的登录我们使用一个标志has_logged_in来判断是否已经登录。如果没有登录我们手动提示登录操作。 提取网页数据 使用Selenium获取当前页面的源代码后使用lxml.etree解析HTML。通过XPath选择器我们提取职位的相关信息如职位标题、薪资、公司介绍、职位要求等。 职位标题tree.xpath(/html/body/section[3]/div[1]/div[1]/span[1]/span/text())薪资tree.xpath(//span[classsalary]/text())公司信息包括公司名称、公司介绍等均通过XPath进行提取。 处理提取错误 使用try-except语句来处理数据提取过程中可能出现的错误避免程序中断。即使某个字段没有数据代码仍然会继续运行确保尽可能多地提取到有效数据。 将数据写入CSV 提取的数据被按行写入CSV文件包含公司名称、职位信息、薪资、工作要求等字段。 关闭WebDriver 在所有请求处理完毕后调用driver.quit()关闭浏览器实例释放资源。
代码示例
# 从文件中读取失败的请求URL
with open(failed_requests.txt) as f:failed_requests [line.strip() for line in f.readlines()]# 设置Selenium WebDriver
driver webdriver.Chrome()
driver.implicitly_wait(3)has_logged_in False# 打开CSV文件用于写入数据
with open(failed_requests_data.csv, modew, newline, encodingutf-8) as file:writer csv.writer(file)# 写入表头writer.writerow([Company Name, Company Intro, Job Intro, Job Location, Job Experience, Job Education, Title,Salary, Key Words, Company Info, Details URL])for failed_request in failed_requests:driver.get(failed_request)if not has_logged_in:input(请登录)has_logged_in True# 提取数据title tree.xpath(/html/body/section[3]/div[1]/div[1]/span[1]/span/text())[0] if tree.xpath(/html/body/section[3]/div[1]/div[1]/span[1]/span/text()) else salary tree.xpath(//span[classsalary]/text())[0] if tree.xpath(//span[classsalary]/text()) else company_name tree.xpath(//div[classname ellipsis-1]/text())[0] if tree.xpath(//div[classname ellipsis-1]/text()) else company_intro tree.xpath(//div[classinner ellipsis-3]/text())[0] if tree.xpath(//div[classinner ellipsis-3]/text()) else job_intro tree.xpath(//dd[data-selectorjob-intro-content]/text())[0] if tree.xpath(//dd[data-selectorjob-intro-content]/text()) else job_loca tree.xpath(/html/body/section[3]/div[1]/div[3]/span[1]/text())[0] if tree.xpath(/html/body/section[3]/div[1]/div[3]/span[1]/text()) else # 关闭WebDriver
driver.quit()代码说明
WebDriverWait用于等待网页中的某个元素加载完成避免程序在页面未加载完毕时就进行数据提取。XPath提取tree.xpath()用于从HTML中提取相关数据XPath的使用使得提取过程更加灵活和精确。CSV写入提取到的数据被写入到CSV文件中方便后续分析。
最后爬取的数据结果 总结
本项目通过 Scrapy 框架结合 JS 逆向技术和自定义中间件成功地爬取了猎聘招聘平台的数据并存储在本地 CSV 文件中。重试机制和代理设置保证了爬虫的稳定性和反爬虫防护。该方案适用于类似需要绕过反爬虫机制的招聘网站或其他数据来源。
如果你对 Web 爬虫的其他技术和最佳实践感兴趣欢迎关注本博客。
需要源代码的添加我