本次目标:
了解session和cookie,ip代理知识,selenium的使用,拔高:实现丁香园的模拟登录爬取留言板
session和cookie
因为http是无状态的,就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。这种无状态的的好处是快速。坏处是假如我们想要把www.zhihu.com/login.html和www.zhihu.com/index.html关联起来,必须使用某些手段和工具。
由于http的无状态性,为了使某个域名下的所有网页能够共享某些数据,session和cookie出现了。客户端访问服务器的流程如下
- 首先,客户端会发送一个http请求到服务器端。
- 服务器端接受客户端请求后,建立一个session,并发送一个http响应到客户端,这个响应头,其中就包含Set-Cookie头部。
- 在客户端发起的第二次请求,假如服务器给了set-Cookie,浏览器会自动在请求头中添加cookie
- 服务器接收请求,分解cookie,验证信息,核对成功后返回response给客户端
简而言之, session 有如用户信息档案表, 里面包含了用户的认证信息和登录状态等信息. 而 cookie 就是用户通行证。
token
token 也称作令牌,由uid+time+sign[+固定参数]
token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。
ip代理知识
- 无代理:显示自己ip
- 透明代理:仍然显示IP
- 匿名代理:隐藏真实IP,但是向访问对象透露使用代理服务器访问他们的。
- 欺骗性代理:告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。
- 高匿名代理:完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象。
selenium的使用
selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
selenium用于爬虫,类似于使用代码来控制你的服务器,以便进行网站搜索和数据爬取。
安装driver
查看chrome版本:chrome://version/
下载对应版本的driver:driver
使用selenium控制chrome,并进行查找python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time
browser=webdriver.Chrome()
try:
browser.get("https://www.baidu.com")
input=browser.find_element_by_id("kw")
input.send_keys("Python")
input.send_keys(Keys.ENTER)
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,"content_left")))
print(browser.current_url)
print(browser.get_cookies())
print(browser.page_source)
time.sleep(10)
finally:
browser.close()
结果如图:
selenium功能:
- 控制浏览器
- 访问网页
- 查找元素
- 执行js
- 获取元素信息
- 浏览器的前进和后退
- cookies的处理
丁香园评论爬取
import time
from selenium import webdriver
import csv
from lxml import etree
browser = webdriver.Chrome() # 先模拟登录
url = 'http://www.dxy.cn/bbs/thread/626626#626626/' #丁香医生
browser.get(url)
time.sleep(3)
browser.maximize_window()#打开网页窗口
time.sleep(4)
#denglu = browser.find_element_by_class_name("activate-info-tip-btn")[1]#账号输入框 'FirefoxWebElement' object does not support indexing
denglu = browser.find_element_by_xpath('//div[@class="nav_account"]/a') #找到第一个a节点
denglu.click() #点击进入到登录网站
time.sleep(4)
dl = browser.find_element_by_xpath('//a/i[@class="wechat__ico ico_pc"]')
dl.click()
time.sleep(5) #这里进入电脑版登录界面
input= browser.find_element_by_name("username") #找到账号输入的地方
input.send_keys("17353239795")
password = browser.find_element_by_name("password")#密码输入框
password.send_keys('wq1255462268')
login_em = browser.find_element_by_class_name("button")#登录按钮
login_em.click()
time.sleep(15) #需要验证码 要显示登录成功啊。。。。加上人工操作点击验证
cookie = browser.get_cookies()
cookie_dict = {i['name']: i['value'] for i in cookie}
# 转到抓取页面
browser.get(url)
html = browser.page_source
html = etree.HTML(html)
result1 = html.xpath('//div[@class="auth"]') #评论者姓名
result2 = html.xpath('//div[@class="info clearfix"]')
result3 = html.xpath('//div[@class="user_atten"]/ul/li[1]')
result4 = html.xpath('//div[@class="user_atten"]/ul/li[2]')
result5 = html.xpath('//div[@class="user_atten"]/ul/li[3]')
result6 = html.xpath('//tbody//td[@class="postbody"]') # 取出对应的回复评论 都是list型
result7 = html.xpath('//div[@class="post-info"]/span[1]')
# 创建空列表存放数据
user = []
level = []
jifen = []
depiao = []
dingdang = []
content = []
time = []
with open("dingxiang4.csv", 'a', encoding='utf-8',newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["user", "level","jifen","depiao","dingdang","content", "time"])
for data in result1:
x = data.xpath('string(.)') .strip() # 对单个对象去掉换行符,只留下字符串
user.append(x) # 做成字典型
for data in result2:
y = data.xpath('string(.)').strip()
level.append(y)
for data in result3:
z = data.xpath('string(.)').strip()
jifen.append(z)
for data in result4:
x = data.xpath('string(.)').strip() # 对单个对象去掉换行符,只留下字符串
depiao.append(x) # 做成字典型
for data in result5:
x = data.xpath('string(.)').strip() # 对单个对象去掉换行符,只留下字符串
dingdang.append(x) # 做成字典型
for data in result6:
x = data.xpath('string(.)').strip() # 对单个对象去掉换行符,只留下字符串
content.append(x) # 做成字典型
for data in result7:
x = data.xpath('string(.)').strip() # 对单个对象去掉换行符,只留下字符串
time.append(x) # 做成字典型
print(len(content))
for i in range(len(user)):
result = user[i],level[i] ,jifen[i],depiao[i],dingdang[i],content[i], time[i]
print(result)
writer.writerow(result)