爬虫实战1-批量获取公开政策文本

本文未展示图片,可以跳转到我的博客园浏览代码和操作流程~

博客园-艽野尘梦

目标:爬取北京市公开发布的所有人才引进相关的政策文本

准备:1、环境 Python 3.7,2、使用 selenium 库中的 webdriver,3、安装对应版本的 chromedriver

url:在北京市人民政府网站上,人才引进相关政策的 url 地址是:https://www.beijing.gov.cn/so/s?siteCode=1100000088&tab=zcfg&qt=%E4%BA%BA%E6%89%8D%E5%BC%95%E8%BF%9B

一些参考:(1 条消息) Python 爬虫(1)一次性搞定 Selenium(新版)8 种 find_element 元素定位方式_find_element(by.class_name_轻烟飘荡的博客 - CSDN 博客

(1 条消息) Selenium — 标签 class 及其他属性值更改_selenium 修改属性值_Ethel L 的博客 - CSDN 博客

目标网站 html 内容

在浏览器输入 url,可以看见网站的基本内容见下图,我们需要爬取的是图中画线部分:

接下来看一下画线部分的 html 文本,可以看见每一个政策条目都都在 class 为’search-result’的 div 标签里,查看这个 div 标签,我们可以看见政策的类型,标题,链接等内容。

那么只需要找到所有的 class 为’search-result’的 div 标签,然后循环搜索里面的信息(注意 a 标签里的链接是关键信息,后续需要爬取链接里的具体政策内容),并保存到 csv 文件中。这里使用的是 find_element_XX_XX 函数,如果 selenium 版本比较新,可能这几个函数无法使用了,可以改为使用 find_element(By.xx,‘xx’),这里需要引入 selenium.webdriver.common.by。

解决 js 渲染的翻页内容

在查看网页的过程中,发现跳转下一页的内容,url 并未发生变化,是根据 JavaScript 动态渲染出的内容,这里就使用 find_element 找到下一页的按钮然后 click 它。代码位于 29 行和 44 行。

解决搜索位置的切换

还有一个需求是按标题检索含有 “人才引进” 的政策文本,查看 html 发现,这两个在交互中能够点击的标签在 html 中是 div 标签,一般来说,div 标签是无法点击的,并且初步来看这里没有 js 代码,但是切换搜索位置是全文还是标签,url 并没有改变。这也是我比较困惑的地方,如果有了解的大佬可以在评论中解决一下我的疑惑。虽然不太知道这里的原因,但是我发现点击标题,则标题的 class 变为 position-con item-choose item-choose-on,全文的 class 变为 position-con item-choose,点击全文则反过来,那么我们可以执行 js 代码修改这两个标签的属性,实现搜索位置的切换,代码位于 17-21 行。

具体代码如下:

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 28 16:46:21 2023

@author:
"""

from selenium import webdriver
import time
import pandas as pd
from selenium.webdriver.common.by import By

browser=webdriver.Chrome()
browser.get('https://www.beijing.gov.cn/so/s?siteCode=1100000088&tab=zcfg&qt=%E4%BA%BA%E6%89%8D%E5%BC%95%E8%BF%9B')
time.sleep(5)

lable=browser.find_elements(By.CSS_SELECTOR,'.position-con.item-choose')#查找全文和标题的检索项
print(lable[0].text,lable[1].text)
js= 'arguments[0].setAttribute(arguments[1],arguments[2])'
browser.execute_script(js,lable[0],'class','position-con item-choose')#修改全文标签的class
browser.execute_script(js,lable[1],'class','position-con item-choose item-choose-on')#修改标题标签的class


time.sleep(2)
data=pd.DataFrame([],columns=['类型','链接','标题','文号','发文机构','主题分类','发布日期'])
page=1
while page:
    if page !=1:
        page.click()
        time.sleep(1)
    poli=browser.find_elements_by_class_name('search-result')
    for elements in poli:#一个elements是一个记录
        p_type=elements.find_element_by_class_name("result-header-lable").text#政策类型
        link=elements.find_element_by_tag_name("a").get_attribute('href')#链接
        title=elements.find_element_by_tag_name("a").text#标题
        table=elements.find_elements_by_class_name("row-content")#文号、发文机构、主题分类、发布日期
        content=[p_type,link,title]
        for item in table:
            content.append(item.text)
        while len(content)<7:
            content.append(0)
        content=pd.DataFrame([content],columns=['类型','链接','标题','文号','发文机构','主题分类','发布日期'])
        data=pd.concat([data,content])
    page=browser.find_element_by_class_name('next')
data.to_csv(r'人才政策爬取\北京市人才政策.csv',encoding='utf_8_sig',index=False)

提取政策的具体内容

在上面的代码中,我们实现了爬取所有标题含 “人才引进” 的政策的大致信息,结果类似下图的表格内容。

接下来需要做的是逐个读取每个政策的链接,将其中的文本内容提取到 txt 文件中,从 html 文本中可以看到文本内容均位于 id='mainText’的 div 标签中,每个 p 标签为一个需要换行的段落。

下面的代码实现了这个过程:

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 28 21:41:39 2023

@author:
"""

import pandas as pd
from selenium import webdriver
import time
import numpy as np
from selenium.webdriver.common.by import By

files=pd.read_csv(r'人才政策爬取\北京市人才政策.csv',\
                  encoding='utf-8',header=0)
files_link=files[['链接','标题']]
files_link=np.array(files_link)
files_link=files_link.tolist()
print(files_link)
browser=webdriver.Chrome()
time.sleep(3)
for link,title in files_link:
    with open(r"人才政策爬取\北京市政策文本\\"+title+'.txt',"w") as f:
        f.write(title+'\n')
        browser.get(link)
        time.sleep(1)
        out_time=browser.find_element_by_xpath("//*[contains(text(),'[发布日期]')]").text
        f.write(out_time+'\n')
        content=browser.find_element(By.ID,'mainText')
        lines=content.find_elements_by_tag_name('p')
        for line in lines:
            f.write(line.text+'\n')

猜你喜欢

转载自blog.csdn.net/qq_45270849/article/details/130383978
今日推荐