文章目录
浅浅记录一下自己在做一个比赛数据处理过程中的遇到的一些问题。
一、需求
首先数据的格式是长下面图片这样的,左边是网站链接,右边是网站分类的标签,然后我要做的工作就是访问每个网站将网站的文本爬取下放在每个链接后边。
二、爬取阶段
下面就是我的尝试过程了😂
1.使用requests进行请求获取网页内容
import requests
from fake_useragent import UserAgent
def completionUrl(url):
'''对url进行补全'''
if "http" in url:
return url
else:
url = f"http://" + url.strip('"')
return url
def getContent(url):
'''获取网页源代码'''
# 对url进行补全
url = completionUrl(url)
# 发送请求获取网页内容
# 设置随机useragent简单防爬
headers = {"User-Agent": UserAgent().random}
try:
resp = requests.get(url=url, headers=headers, verify=False)
# print(resp.encoding) # 查看返回内容的编码 针对对应的特殊编码进行解码
if resp.encoding == "ISO-8859-1":
# 解决ISO-8859-1编码问题
html = resp.text.encode('ISO-8859-1').decode(requests.utils.get_encodings_from_content(resp.text)[0])
# print(html)
else:
html = resp.text
print(f"url:{url} html:{html}")
return html
# 处理网站请求失败的情况
except Exception as e:
# print(f"ERROR of {url}",e)
html = "网站请求失败"
print(f"url:{url} html:{html}")
return html
if __name__ == '__main__':
url = "www.baidu.com"
content = getContent(url)
在使用requests发请求获取网页内容的时候发现,就是很多网站有针对requests请求的反爬机制。导致很多网站的数据无法获取,这个时候我就想到了模拟人的行为操作浏览器获取数据,虽然使用selenium可能也有部分网站会有反爬,但是情况应该比使用requests要好很多。
2.使用selenium模拟人操作浏览器获取网页内容
(1)环境配置
具体步骤可以参考博客microsoft edge驱动器下载以及使用
在使用selenium进行爬取之前,先要下载好相应的浏览器驱动。我用的是edge浏览器,所以我就下载edge浏览器的驱动。
根据你edge浏览器的版本,下载对应版本的驱动,可以看到我edge浏览器的版本号是109.0.1518.55
。
下载好了之后将msedgedriver.exe
放置到你使用python环境中python.exe的同级目录下。
之后就是下载selenium包到你所用的环境即可。
(2) 源码
from selenium import webdriver
from fake_useragent import UserAgent
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def completionUrl(url):
'''对url进行补全'''
if "http" in url:
return url
else:
url = f"http://" + url.strip('"')
return url
def driver():
'''获取浏览器驱动对象'''
# 准备好参数配置,将该参数传入Edge可以使其不弹出窗口 但是这个对selenium的版本要求较高,较低版本没有这个参数
opt = Options()
# opt.add_argument("--headless")
# opt.add_argument('--disable-gpu')
# # 设置随机user-agent 简单防爬
# opt.add_argument(f'user-agent={UserAgent().random}')
# 解决浏览器加载时间过长的问题
# opt.page_load_strategy = 'eager'
# driver = webdriver.Edge(options=opt)
driver = webdriver.Edge()
# 设置请求时间
driver.set_page_load_timeout(15)
return driver
def getHtmlBySelenium(url,driver):
'''使用浏览器驱动对象获取网页内容'''
# 对url进行补全
url = completionUrl(url)
html = driver.get(url)
# 获取网页源码
html = driver.execute_script("return document.documentElement.outerHTML")
return html
if __name__ == '__main__':
# 使用selenium模拟人操作浏览器获取网页内容
url = "www.baidu.com"
driver_ = driver()
html = getHtmlBySelenium(url,driver_)
print(f"html:{html}")
参考博客:
Selenium 等待与超时(一) - 知乎 (zhihu.com)
selenium之chrome浏览器设置userAgent和代理ip_夜阑卧听风吹雨,铁马冰河入梦来的博客-CSDN博客_selenium useragent
当我使用selenium之后还是发现了一些问题,每次使用edge浏览器爬取了差不多100个网址之后就不行了,后来怀疑是浏览器驱动的问题,换成了无头浏览器phantomjs。
3.使用phantomjs模拟人操作浏览器获取网页内容
安装使用可参考博客:
- phantomjs下载安装与使用_李汶峰的博客-CSDN博客_下载plantomjs
- Python爬虫:selenium使用chrome和PhantomJS实用参数_彭世瑜的博客-CSDN博客
但是phantomjs对selenium的版本有所要求,新版selenium不支持PhantomJS 要用老版本吗 · Issue #48 · sczhengyabin/Image-Downloader (github.com),需要安装指定的selenium版本才可以使用。
from selenium import webdriver
from fake_useragent import UserAgent
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def completionUrl(url):
'''对url进行补全'''
if "http" in url:
return url
else:
url = f"http://" + url.strip('"')
return url
def driver():
'''获取浏览器驱动对象'''
dcap = dict(DesiredCapabilities.PHANTOMJS)
# 设置user-agent请求头
dcap["phantomjs.page.settings.userAgent"] = UserAgent().random
# 禁止加载图片
dcap["phantomjs.page.settings.loadImages"] = False
driver = webdriver.PhantomJS(desired_capabilities=dcap)
# 设置请求时间
driver.set_page_load_timeout(15)
return driver
def getHtmlBySelenium(url,driver):
'''使用浏览器驱动对象获取网页内容'''
# 对url进行补全
url = completionUrl(url)
html = driver.get(url)
# 获取网页源码
html = driver.execute_script("return document.documentElement.outerHTML")
return html
if __name__ == '__main__':
# 使用selenium模拟人操作浏览器获取网页内容
url = "www.baidu.com"
driver_ = driver()
html = getHtmlBySelenium(url,driver_)
print(f"html:{html}")
最后发现确实phantomjs浏览器驱动比edge浏览器驱动好用。
4.使用phantomjs模拟人操作浏览器获取网页截图
由于在预测任务中,我们除了需要提供文本之外还需要提供对应的网页截图,一下的代码为使用phantomjs模拟人操作浏览器获取网页截图的源码。
from PIL import Image
from utils_.utils import processUrl
from selenium import webdriver
from fake_useragent import UserAgent
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def Driver():
'''获取浏览器驱动对象'''
dcap = dict(DesiredCapabilities.PHANTOMJS)
# 设置user-agent请求头
dcap["phantomjs.page.settings.userAgent"] = UserAgent().random
service_args = []
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误
driver = webdriver.PhantomJS(service_args=service_args,desired_capabilities=dcap)
driver.set_window_size(1300, 800)
driver.set_page_load_timeout(30)
return driver
def get_screenshot(url,screenshot_save_path):
'''获取网页截图'''
try:
url = processUrl(url)
driver.get(url)
# wait = WebDriverWait(browser, 10)
# # 设置判断条件:等待id='kw'的元素加载完成
# input = wait.until(EC.presence_of_all_elements_located)
# print("加载完成!")
except:
# print("加载超时!")
driver.execute_script('window.stop()')
finally:
# browser.find_element_by_id("idClose").click()
# time.sleep(5)
# print("正在保存截图..")
try:
driver.save_screenshot(screenshot_save_path+str(1)+".png")
# print("----------------保存成功---------------------") # print("正在处理网页截图...")
im=Image.open(screenshot_save_path+str(1)+".png")
left = 0
top = 0
right = 1300
bottom = 800
im=im.crop((left,top,right,bottom))
im.save(screenshot_save_path+str(1)+".png")
img = Image.open(screenshot_save_path+str(1)+".png")
img.show()
print("sceenshot:截图保存成功!!!")
except Exception as e:
print(f"截图保存失败,catch error:{e}")
driver.quit()
global driver
driver = Driver()
if __name__ == '__main__':
screenshot_save_path = "../web_page_screenshot/"
url = "www.baidu.com"
get_screenshot(url,screenshot_save_path)