爬虫项目的简单总结
上面两个文章主要展示了两个Selenium爬虫的具体程序,对于中间遇到的小的问题和具体内容的实现在这里进行简单的介绍和总结。
1、通过Cookie实现网站登陆
保存Cookie
## 保存网站cookie
from selenium import webdriver
import os
import time
import json
## 获取Cookie
def get_cookies(url,filepath):
browser = webdriver.Chrome()
browser.get(url)
## 扫码
time.sleep(20)
dictCookies = browser.get_cookies()
# 转换成字符串保存
jsonCookies = json.dumps(dictCookies)
with open("./json/cookies.json", 'w') as f:
f.write(jsonCookies)
print('cookies保存成功!')
browser.quit()
log_url = 'https://www.zhipin.com/?city=100010000&ka=city-sites-100010000'
file = './json/bosscookies.json'
get_cookies(log_url,file)
测试Cookie
# !/usr/bin/python3.4
# -*- coding: utf-8 -*-
## 实现登陆
from selenium import webdriver
import os
import time
import json
def getCookie(browser,url):
with open('./json/cookies.json', 'r', encoding='utf8') as f:
listCookies = json.loads(f.read())
for cookie in listCookies:
cookie_dict = {
'domain': '.zhipin.com',
'name': cookie.get('name'),
'value': cookie.get('value'),
'path': '/',
"expires": '',
'sameSite': 'None',
'secure': cookie.get('secure')
}
browser.add_cookie(cookie_dict)
browser = webdriver.Chrome()
url = "https://www.zhipin.com/?city=100010000&ka=city-sites-100010000"
browser.get(url)
newwindow='window.open("https://www.zhipin.com/?city=100010000&ka=city-sites-100010000");'
# 删除原来的cookie
browser.delete_all_cookies()
# 携带cookie打开
getCookie(browser,url)
# 通过js新打开一个窗口
browser.execute_script(newwindow)
input("查看效果")
browser.quit()
上面的程序参考了这篇文章:利用selenium携带cookies实现免登录
2、Selenium元素定位
以百度的网页为例,在进行对webdriver通过xpath进行元素定位时可以通过下面的步骤快速定位:页面右键点击检查;之后找到当前按钮"登陆"的代码部分;右键copy可以直接得到在当前页面获得该元素的xpath,非常简单高效。
在使用webdriver进行元素定位时可以对得到的结果再次进行元素定位,可以更好对程序进行设计和处理。
中间在处理table中的tb、td时出现了一个问题:Xpath无法解析(tbody)。这个感觉是网站的问题,后来更换了爬取的页面,就没有这个问题了。关于这个问题的具体描述和分析可以参考这篇文章:Python爬虫——从浏览器复制的Xpath无法解析(tbody)
——————————————————————————
补充一下Selenium中对元素定位,在进行点击时可能会出现报错,就是可以找点界面中的元素但是click() 之后页面没有刷新。这时候可以增加slepp的时间等待界面加载,另一个就是调用其他方法:
## driver.find_element_by_xpath('//*[@id="search-jobs-clear-options"]').click()
## 上面方式失效 采用下面的实现方法
button = driver.find_element_by_xpath('//*[@id="search-jobs-clear-options"]')
webdriver.ActionChains(driver).move_to_element(button).click(button).perform()
3、Selenium webdriver 实现账号密码登陆
通过webdriver 的find_element_by_id(“password”)可以定位到每个网站的账号密码的输入位置,然后传入已有的字符串就可以实现登陆。这种登陆方式可以解决很多网站的登陆问题。
def Login():
Name = "******"
Password = "********"
# 输入账号
time.sleep(4)
driver.find_element_by_id("username").send_keys(Name)
# 输入密码
driver.find_element_by_id("password").send_keys(Password)
time.sleep(4)
# 点击登录按钮
driver.find_element_by_id("submit_id").click()
time.sleep(4)
4、链家房价爬取
爬取链家中所有地区的房价是半年前最开始测试的一个爬虫,主要用的requests。这个爬虫数据获取的比较快,但是之前IP就总是被检测出来,然后进行安全验证。当时就是爬取一个地区的对数据进行保存,进行完安全验证,在原来数据的基础上接着爬。然后勉强拼凑除了全国的房价数据。现在测试一下原来的爬虫,随便爬一下就要进行安全验证。相比于Selenium下的爬虫,速度虽然满了一点,但是爬取数据很稳定,从做完调试到爬取完数据,中间就没有进行过安全验证。文章貌似会审核不通过,具体程序可以去Github上查看
5、Boss和liepin工作信息的爬取
之前发布的爬取Boss工作信息的爬虫的博客审核未通过。具体爬虫后面会放在Github上在来补充。
liepin的爬虫可以爬取13个热门城市的所有工作信息。爬虫主要使用webdriver和requests。
liepin爬取的数据如下:
5、代理池proxy-pool
代理池的问题主要用的Github上的proxy_pool和 ProxyPool两种方式获取免费的代理,使用这种免费的透明代理,如果爬取得频率较高也是很容易被网站检测出来原始的IP的。但是可以构建和实现一下。
——————————————————————————————————————————
代理补充:通过proxy_pool在本地端口可以刷新获取一些免费的代理,pool会不断更新本地的IP池,从中获取代理信息,并在headers中添加proxies,requests 请求http://httpbin.org/get?show_env=1 提取返回的htlm文本信息,如果返回请求的html文件包含本机IP则说明该代理不是匿名代理,通过这种方法,可以从本地的IP池中筛选获得一些高匿名的代理,这些代理用于爬虫就很方便。
具体程序可以参考如下:
import requests
import re
## proxy_pool的使用
## 参考
def get_proxy():
return requests.get("http://127.0.0.1:5010/get/").json()
def delete_proxy(proxy):
requests.get("http://127.0.0.1:5010/delete/?proxy={}".format(proxy))
ipinfourl = "http://httpbin.org/get?show_env=1"
## 你本机的公网IP地址
## 通过访问http://httpbin.org/ip 可以查看
ipcomputer = "**********"
ipAccess={"http://120.220.220.95:8085"}
## 从代理池中获取10个代理IP,并将高匿代理信息放在集合ipAccess中
for i in range(0,10):
#获取IP代理
proxy = get_proxy().get("proxy")
proxies={"http": "http://{}".format(proxy)}
print("当前测试代理:" + proxies["http"])
#检查ip
try:
iptest = requests.get(url=ipinfourl,proxies=proxies,timeout=(10, 15))
if not iptest:
delete_proxy(proxy)
print("请求超时,删除该代理")
else:
## 正则表达式获取添加代理后IP匿名情况
new = re.findall(r"\d+\.\d+\.\d+\.\d+",iptest.text)
if new:
if ipcomputer in new:
print("...透明代理...")
else:
ipAccess.add(proxies["http"])
print(".....................匿名IP:%s....succes"% proxies["http"])
except Exception as e:
delete_proxy(proxy)
print("当前代理无法访问,删除该代理.....")
continue
print("——————————IP测试结束————————")
不足:上面对非匿名代理以及代理是否能用的判断的逻辑上存在一些混乱,但是最后筛选出的匿名代理是有效的
程序运行结果如下