前段时间有个数据源网站突然更新,原本通过websocket爬取的数据突然就gg了。没得办法,只能用最原始的方法来爬取想要的数据了。爬取过不少的网站数据,这里不对爬虫合理合法性做讨论。纯粹分享我知道的一点点技术
网站大体分三种(对于爬虫而言)
⒈网站直接通过接口获取数据(json和页面)。简单的就是通过传一些params来获取不同数据,这种是最简单的。通过requests模块就可以很容易拿到自己想要的数据。json数据好说,直接解析json就可以。另一种是接口返回的是网页源代码,这种稍稍麻烦些,也不难,scrapy这个框架就是好用,xpath也是神器。简单学习下,爬取个网站不在话下。
⒉第二种是网站通过websocket获取数据。这种我原先也觉得简单,不就是用websocket嘛,验证ssl直接关闭就行了嘛。
import websocket
def create_ws():
try:
header = [
"User - Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
]
ws = websocket.create_connection(
url='wss://*******',
timeout=60,
header=header,
# subprotocols=["binary", "base64"],
sslopt={"cert_reqs": ssl.CERT_NONE}
)
print("ok")
except Exception as e:
log.error("连接ws {}".format(e))
ws = None
return ws
无非就是subprotocols=["binary", "base64"],sslopt={"cert_reqs": ssl.CERT_NONE}设置这两种验证模式,这种方法也让我解决了大部分网站的websocket。直到网站更新后使用ssl.PROTOCOL_SSLv2协议,检测出我这个爬虫一直强制断开我的连接。
websocket连接最麻烦,如果验证通过就可以获取到传过来的数据了。具体连接方式和发送接收消息方法参考下面链接
https://pypi.org/project/websocket_client/
⒊使用selenium webdriver启动浏览器爬取。理论上这种方式可以获取百分之九十九的网站数据
def domain(self):
options = webdriver.ChromeOptions()
# 后台运行浏览器,不显示
options.add_argument("--headless")
# 禁用gpu加速
options.add_argument("--disable-gpu")
# 日志等级
options.add_argument('log-level=3')
driver = webdriver.Chrome(options=options)
# 设置窗口大小
driver.set_window_size(1920, 1080)
# 删除cookies
driver.delete_all_cookies()
# 最长加载页面时间
driver.set_page_load_timeout(60)
url = "https://******"
driver.get(url)
# 最大窗口化
driver.maximize_window()
time.sleep(2)
基本设置项这么多,还有个更换浏览器请求头。
options.add_argument('user-agent="Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"')
启动差不多就到这了,然后还有浏览器启动记住要关闭。本人吃亏上当过,没有关闭浏览器,用的多线程启动浏览器。报错就新开一个,服务器被我搞炸了,不过因此也牢牢记住了启动就要想想关闭
# 关闭当前页面
driver.close()
# 关闭浏览器
driver.quit()
启动关闭完成,现在就是从页面获取数据。
# xpath 遵从xpath规则 //div[@class='**** ****']" 多个class用空格
driver.find_element_by_xpath()
# 名字可知 通过classname 但是只能填一个
driver.find_element_by_class_name()
# css选择器,百度下就知道,不赘述 我用得少
driver.find_element_by_css_selector()
# 上面element单数,默认选取第一个 下面是list集合
driver.find_elements_by_xpath()
driver.find_elements_by_class_name()
driver.find_elements_by_css_selector()
上面这些获取的都是element对象。他们也可以接着使用上面方法获取子节点对象(driver代表最上层吧,嗯,我这么理解)
节点还有其他经常用的方法。
# 点击操作
element.click()
# 获取自定义属性
element.get_attribute('title')
str = element.text
id = element.id
# 键盘操作
# from selenium.webdriver.common.keys import Keys
element.send_keys(Keys.Enter)
数据操作方面就涉及到这些,其他的就是自己逻辑处理和数据处理解析了。这里赘述一下,使用driver.find_elements_by_xpath()获取到的list遍历时,接着使用xpath获取子节点时,会出bug。拿到的是全局的对象,并不是想要的子节点。
最后补充一下,浏览器的刷新和后退
driver.refresh()
driver.back()
综上,使用这些技术基本爬取一个网站数据就没问题了,但是爬虫和反爬之间的斗争用不停歇,大家各自努力。有啥问题欢迎指正
作者:言格与甄意