AI应用开发相关目录
本专栏包括AI应用开发相关内容分享,包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧
适用于具备一定算法及Python使用基础的人群
- AI应用开发流程概述
- Visual Studio Code及Remote Development插件远程开发
- git开源项目的一些问题及镜像解决办法
- python实现UDP报文通信
- python实现日志生成及定期清理
- Linux终端命令Screen常见用法
- python实现redis数据存储
- python字符串转字典
- python实现文本向量化及文本相似度计算
- python对MySQL数据的常见使用
- 一文总结python的异常数据处理示例
- 基于selenium和bs4的通用数据采集技术(附代码)
一、前言
本文所说的数据采集技术即爬虫,爬虫技术用于从互联网上抓取大量数据。这些爬虫程序能够自动化地访问网页/公众号平台、解析内容,并提取所需的信息。在大数据和机器学习等领域,爬虫技术发挥着至关重要的作用。
数据采集技术为项目提供丰富的数据资源,根据这些信息进行产品设计和创新,持续改进和优化产品。
二、环境配置
pip install beautifulsoup4
pip install selenium
安装WebDriver:Selenium需要WebDriver来与浏览器进行交互。不同的浏览器需要不同的WebDriver。例如,如果你使用的是Chrome浏览器,你需要下载并安装chromedriver;如果你使用的是Firefox浏览器,你需要下载并安装geckodriver。请根据你的浏览器类型,从官方网站或相关源下载对应的WebDriver,并将其放置在系统路径下,以便Selenium能够找到并调用它。
三、技术策略
http://ytzwfw.sd.gov.cn/yt/icity/project/index
特性1:翻页后url无变化规律
特性2:数据爬取分为2阶段,需要在url后再爬取具体数据项的url_son,再针对url_son设计程序采集。
特性3:html源码中无法直接获取数据存在形式,仅开发者模式下才能观察到
由此可知该网站具备相当程度的反扒设计。
策略:
设计两个阶段
的数据采集程序,克服特点2
。
采取selenium自动化框架
,克服特点1
。
采取bs4数据采集框架
,客服特点3
。
四、代码实例
step1:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
def get_single_page_data():
result = []
for i in range(10):
try:
mid_title = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']/div[1]/a[1]').text
mid_url = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']/div[1]/a[1]').get_attribute('onclick')
mid = [mid_title,mid_title,mid_url.split("'")[-2]]
# print(mid)
result.append(mid)
except:
print('data error!')
return result
def write_data_totxt(data:str):
with open('data.txt', 'a') as f:
f.write(data)
f.write('\n')
# 创建一个Chrome浏览器实例
driver = webdriver.Chrome(options=Options(), executable_path=r'C:\Program Files\Google\Chrome\Application\chromedriver.exe')
# 打开目标网页
driver.get("http://ytzwfw.sd.gov.cn/yt/icity/project/index")
data = []
page = 0
while page<= 628: # 循环页数
try:
single_page_data = get_single_page_data() # 抓数据
for i in single_page_data:
print(i)
write_data_totxt(i[0])
write_data_totxt(i[-1])
# /html/body/div[5]/div/div/div[2]/div/a[8]
driver.find_element(By.CLASS_NAME, 'laypage_next').click() # 翻页
time.sleep(2)
page += 1
except:
print('page error!')
driver.quit()
爬取结果如下所示:
step2:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import requests
from bs4 import BeautifulSoup
def get_end_time(url):
options = webdriver.ChromeOptions()
# 添加无头模式选项
options.add_argument("--headless")
# 创建一个Chrome浏览器实例
driver = webdriver.Chrome(options=options, executable_path=r'C:\Program Files\Google\Chrome\Application\chromedriver.exe')
# 打开目标网页
driver.get(url)
goal = driver.find_element(By.CLASS_NAME, 'law-time').text
driver.quit()
return goal
def getHTMLText(url, timeout=30):
try:
r = requests.get(url, timeout=30) # 用requests抓取网页信息
r.raise_for_status() # 可以让程序产生异常时停止程序
r.encoding = r.apparent_encoding
return r.text
except:
return '产生异常'
def collapse_spaces(s):
while " " in s:
s = s.replace(" ", " ")
return s
def get_single_data(name: str, url: str, data) -> dict:
html = getHTMLText(url)
soup = BeautifulSoup(html, 'html.parser') # 用BeautifulSoup库解析网页
temps_div = soup.find_all('div', attrs={'class': "table-table"})
raw_content_ls = temps_div[0].select('td')
data[name] = {}
data[name]['实施主体'] = raw_content_ls[0].text
data[name]['承办机构'] = raw_content_ls[1].text
data[name]['事项版本'] = raw_content_ls[4].text
data[name]['办理结果名称'] = raw_content_ls[6].text.replace('\n', '').replace('\t', '').replace('\r', '').replace(' ', '')
data[name]['法定办结时限'] = get_end_time(url)
data[name]['是否存在运行系统'] = temps_div[0].select('td[width="30%"]')[-1].text
data[name]['咨询渠道'] = collapse_spaces(
temps_div[0].select('td[colspan="3"]')[-3].text.replace('\r', ' ').replace('\t', ' ').replace('\n', ' '))[1:-1]
data[name]['投诉渠道'] = collapse_spaces(
temps_div[0].select('td[colspan="3"]')[-2].text.replace('\r', ' ').replace('\t', ' ').replace('\n', ' '))[1:-1]
data[name]['受理时间、地点'] = collapse_spaces(
temps_div[0].select('td[colspan="3"]')[-1].text.replace('\r', ' ').replace('\u2003', ' ').replace('\n',
' ').replace(
'\t', ' '))[1:-1]
return data
titles = []
url_ends = []
with open('data.txt','r')as f:
mid = f.readlines()
for i in range(len(mid)):
if i %2 == 0:
titles.append(mid[i].strip('\n'))
else:
url_ends.append(mid[i].strip('\n'))
print(titles[:10])
print(url_ends[:10])
print(len(titles),len(url_ends))
data = {}
start_index = 800
for index in range(len(titles[start_index:start_index+400])):
print(titles[index])
url = 'http://ytzwfw.sd.gov.cn/yt/icity/proinfo/index4ZS?id={url_end}'.format(url_end=url_ends[index])
print(url)
try:
get_single_data(titles[index],url,data)
print(data[titles[index]])
except:
print('error')
print('爬取完成!')
import json
# 将字典转换为JSON格式的字符串
json_string = json.dumps(data, ensure_ascii=False)
# 将JSON字符串写入文本文件
with open('my_dict2.txt', 'w', encoding='utf-8') as file:
file.write(json_string)
'''
with open('my_dict.txt', 'r', encoding='utf-8') as file:
loaded_dict = json.loads(file.read())
print(loaded_dict)
'''
爬取结果如下所示:
如有代码需求,欢迎留言、私信我!
20240328更新
可直接抓取政策项、政策子页、政策分类;应对了政策子页反爬手段。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
import json
def get_single_page_data(result):
for i in range(10):
mid_dict = {
'title': '',
'type': '',
'page': '',
}
try:
folder_flag = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']').get_attribute('is_load')
# 含子页
if folder_flag:
# //*[@id="itemlist"]/div[9]/a[2]
mid_type = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']/a[2]').text
mid_page = str(i + 1)
# //*[@id="itemlist"]/div[9]
code = 'content' + driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']').get_attribute('folder_code')
for j in range(20):
try:
mid_dict = {
'title': '',
'type': '',
'page': '',
}
# //*[@id="content599a1da2-1581-4422-8f90-edbfa009fe5011370600004260520N"]/table/tbody/tr[1]/td[2]/div/a
mid_title = driver.find_element(By.XPATH, '//*[@id="' + code + '"]/table/tbody/tr[' + str(j+1) + ']/td[2]/div/a').get_attribute('text')
print(mid_title)
mid_dict['title'] = mid_title
mid_dict['type'] = mid_type
mid_dict['page'] = mid_page
result.append(mid_dict)
except Exception as e:
print('son page error.')
print(e)
break
# 不含子页
else:
# //*[@id="itemlist"]/div[10]/div[1]/a[1]
# //*[@id="itemlist"]/div[10]/div[1]/a[2]
mid_title = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']/div[1]/a[1]').text
mid_type = driver.find_element(By.XPATH, '//*[@id="itemlist"]/div[' + str(i + 1) + ']/div[1]/a[2]').text
mid_page = str(i + 1)
mid_dict['title'] = mid_title
mid_dict['type'] = mid_type
mid_dict['page'] = mid_page
result.append(mid_dict)
except Exception as e:
print('page error.')
print(e)
return result
def write_data_tojson(data: dict):
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
# 创建一个Chrome浏览器实例
#浏览器启动选项
option=webdriver.ChromeOptions()
#指定为无界面模式
option.add_argument('--headless')
driver = webdriver.Chrome(options=option, executable_path=r'C:\Program Files\Google\Chrome\Application\chromedriver.exe')
# 打开目标网页
driver.get("http://ytzwfw.sd.gov.cn/yt/icity/project/index")
data = []
page = 0
result = []
#while page<= 610: # 循环页数
while page<= 5: # 循环页数
try:
single_page_data = get_single_page_data(result) # 抓数据
write_data_tojson(single_page_data)
# /html/body/div[5]/div/div/div[2]/div/a[8]
driver.find_element(By.CLASS_NAME, 'laypage_next').click() # 翻页
time.sleep(2)
page += 1
except:
print('page error!')
driver.quit()