1.1、Answer:web crawler question 1

1.1、Answer:web crawler question 1

概述

Question 1

1、cookie、JavaScript的关系?怎么产生的cookie?cookie包含哪些内容?JavaScript的功能在crawler代码中通过python的第三方库selenium,selenium用于执行JavaScript的脚本语

言,那selenium是什么?运行脚本语言的脚本语言?

Cookie产生背景

  Cookie背景和意义:web应用包含多个页面,每个页面都对应一个url地址。web浏览器向Web服务器发送了两个请求,申请了两个页面。这两个页面的请求是分别使用了两个单独

的HTTP连接。由于HTTP是无状态的协议,浏览器和Web服务器会在第一个请求完成以后关闭连接通道,在第二个请求的时候重新建立连接。如果没有cookie,Web服务器并不区分

哪个请求来自哪个客户端,对所有的请求都一视同仁,都会针对这些请求建立单独的连接。无状态的协议优点:每个连接资源能够很快被其他客户端所重用;缺点:同一个用户发送的

请求都建立单独的连接产生多余的时间消耗!Cookie:记录用户登陆状态,可以优化HTTP是无状的缺点,而且设置cookie的域范围实现跨三级域名之间的cookie共享,那么有一个问

题如何实现跨二级域名之间的登陆信息共享呢、比如www.taobao.com和www.tmall.com之间就是登陆信息共享的。HTTP1.0版本无状态协议,HTTP1.1版本是支持持久连接的!

一、cookie

假设:web服务器接收到http请求,根据http请求的IP数据包中请求头中的客户端IP(key-value应该有映射关系)、coding(客户端编译器的语言)、浏览器url、等信息,使用???

数据结构抽象出一个结构体保存这些信息。保存在浏览器?这个结构体就是cookie。

拓展:1、JSESSIONID是一个Cookie,Servlet容器(tomcat,jetty)用来记录用户session

cookie

1、web crawler书籍解释:cookie是网站记录和跟踪用户登录凭据,包含用户是否已登录状态信息。cookie结构体包含:令牌、登录有效时限、状态跟踪信息

2、https://www.jianshu.com/p/6fc9cea6daa2解释:http协议本身是无状态的,web客户端使用http协议与web服务器交互,web服务器可以通过每次提交的IP数据包的请求头获取客户

端IP,将web服务器中的资源传递到对应的web客户端,但是web服务器无法跟踪web客户端。web客户端在web浏览器输入url地址(同一资源定位),发送IP数据报web服务端,web

服务端使用response向客户端浏览器颁发一个CookieCookie保存在web浏览器。web浏览器再请求该网站时,web浏览器把请求的网址连同该Cookie一同提交给web服务器。web

服务器检查该Cookie,以此来跟踪用户状态。

二、cookie的结构体

1、https://blog.csdn.net/talking12391239/article/details/9665185的分析:

  Cookie 结构体:Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

NAME=VALUE:NAME是该Cookie的名称,VALUE是该Cookie的值。在字符串“NAME=VALUE”中,不含分号、逗号和空格等字符  

Expires=DATE:Expires变量确定了Cookie有效终止日期。该属性值DATE必须以特定的格式来书写:星期几,DD-MM-YY HH:MM:SS GMT,GMT表示这是格林尼治时间。反之,

不以这样的格式来书写,系统将无法识别。

注:Expires变量可省,如果缺省时,则Cookie的属性值不会保存在用户的硬盘中,而仅仅保存在内存当中,Cookie文件将随着浏览器的关闭而自动消失

Domain=DOMAIN-NAME:Domain变量确定了哪些Internet域中的Web服务器可读取浏览器所存取的Cookie,即只有来自这个域的页面才可以使用Cookie中的信息。这项设置是可选

的,如果缺省时,设置Cookie的属性值为该Web服务器的域名,所指定的域必须以点号(.)来开始如:.cnblogs.com

注:Internet域包含多个web服务器

Path=PATH:Path属性定义了Web服务器上哪些路径下的页面可获取服务器设置的Cookie。一般如果用户输入的URL中的路径部分从第一个字符开始包含Path属性所定义的字符串,

浏览器就认为通过检查。如果Path属性的值为“/”,则Web服务器上所有的WWW资源均可读取该Cookie。同样该项设置是可选的,如果缺省时,则Path的属性值为Web服务器传给浏

览器的资源的路径名。

Secure:Secure变量表明:只有当 web 浏览器和 Web 服务器之间的通信协议为加密认证协议时,浏览器才向服务器提交相应的Cookie。当前这种协议只有一种,即为HTTPS!

max-age: 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。maxAge属性为负数,则表

示该Cookie只是一个临时Cookie,不会被持久化,仅在本浏览器窗口或者本窗口打开的子窗口中有效,关闭浏览器后该Cookie立即失效。maxAge设置为0表示立即删除该Cookie

三、cookie的发送

  web服务器利用响应报头Set-Cookie以键值的方式来发送COOKIE信息,在RFC2109中定义的SET-COOKIE响应报头的格式为:

Set-Cookie: Name = Value; Comment = value; Domain = value; Max-Age = value; Path = Value;Secure; Version = 1 * DIGIT;

注: 1、Name=Value属性值对必须首先出现,在此之后的属性-值对可以以任何顺序出现

   2、Comment属性是可选的,因为Cookie可能包含其它有关用户私有的信息,这个属性允许服务器说明这个Cookie的使用,用户可以检查这个消息

   3、web浏览器会将domain和path都相同的cookie保存在一个文件里,cookie间用*隔开

   4、多个子键值对的cookie格式是name=key1=value1&key2=value2。可以理解为单键值对的值保存一个自定义的多键值字符串

四、cookie:客户端存取cookie、服务器端解析cookie

1、服务器端解析cookie:cookie可以设置不同的域与路径,所以对于同一个name value,在不同域不同路径下是可以重复的,浏览器会按照与当前请求url或页面地址最佳匹配的顺序

来排定先后顺序

2、客户端的存取cookie:web浏览器将后台传递过来的cookie进行管理。开发者在JavaScript中使用document.cookie来存取cookie,但是cookie中设置了HttpOnly属性,那么通过js

脚本(document.cookie)将无法读取到cookie信息,而且document.cookie会由于使用方式不同而表现出不同的行为

2.1、document.cookie并不会覆盖cookie,除非设置的name value domain path都与一个已存在cookie重复

Cookie安全性

       cookie中的数据通常会包含用户的隐私数据,Cookie安全性首先要保证数据的保密性,其次要保证数据不能被伪造或者篡改。基于这两点,cookie内容需要进行加密,加密方式:

对称加密(单密钥,如DES)或非对称加密(一对密钥,如RSA)。密钥需要保存在服务器端一个安全的地方。没有密钥就无法对数据进行解密,也无法伪造或篡改数据。重要的cookie数

据需要设置成HttpOnly的,避免跨站脚本获取你的cookie,保证了cookie在浏览器端的安全性。cookie可以设置只作用于安全的协议(https)通过Cookie类的setSecure(boolean flag)

来设置cookie只会在https下发送,而不会再http下发送,保证了cookie在服务器端的安全性。JavaEE中的Cookie类。

二、selenium

Selenium产生的背景

  web客户端向web服务器发送请求,web服务器向web浏览器响应一个硬编码的HTML模板(不带有任何内容的HTML模板),web浏览器需要单独的Ajax请求来加载内容,并将这些内容放到HTML模板中的正确位置(slot),即HTML创建任务、内容管理系统已经从web服务器端移植到web浏览器端和web客户端。Selenium是web应用程序的测试工具,Selenium直接运行于浏览器中,过程包括:请求硬编码的HTML模板、执行任意的JavaScript、允许加载所有的数据、抓取网页的数据。Selenium加载的数据包括所有的数据,包括‘额外’:调用跟踪程序、加载侧边栏广告、调用侧边栏广告的跟踪程序、图像、CSS、第三方的字体数据等等。这是Selenium的缺点之一:由于在获取页面的过程中会发送很多请求,所以效率非常低,所以在很多时候需要酌情使用。Selenium的优点:Selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易

一、Selenium库包含的模块

1、Selenium库是一个完整的web应用程序测试系统,包括:录制(selenium IDE),编写及运行(Selenium Remote Control)、测试的并行处理(Selenium Grid)

2、Selenium库和JavaScript关系:Selenium获取硬编码的HTML模板(不带有任何内容的HTML模板),Selenium 的 webdiver 中集合了浏览器的中JavaScript的解析操作,Selenium通过driver.execute_script(some JavaScript code ),执行给定的JavaScript代码,加载所有的数据、抓取网页的数据!

3、Selenium库包含的模块:

3.1、webdiver

实例化webdiver对象

from selenium import webdriver

driver= webdriver.Chrome()
driver= webdriver.Firefox()
driver= webdriver.PhantomJS() 
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
driver = webdriver.PhantomJS(desired_capabilities=dcap)

 1、发送GET请求:driver.get(url)

from selenium import webdriver#导入库
driver= webdriver.Chrome()#声明浏览器
url = 'https:www.baidu.com'
driver.get(url)#打开浏览器预设网址
print(browser.page_source)#打印网页源代码
driver.close()#关闭浏览器

2、添加cookie:driver.add_cookie( )、获取cookie:driver.get_cookie( )

# 添加cookie
cookies={
    'username':'xxx',
    'password':'xxx'
}
driver.add_cookie(cookie_dict=cookies)
driver.get('http://example.com')
# 获取cookie
driver.get_cookies()

3、获取当前页面的URL:driver.current_url( )

# 获取当前页面的URL
url=driver.current_url

4、获取HTML源码:driver.page_source( )

# 获取HTML源码
source=driver.page_source

5、刷新:driver.refresh( ) 

# 刷新
driver.refresh()

6、截图:driver.save_screenshot( )  

# 截图
driver.save_screenshot('sougou.png')

7、前进:driver.forward( ) ;后退:driver.back()

# 前进
driver.forward()
# 后退
driver.back()

8、最大化窗口:driver.maximize_window( ) ;关闭当前页面(如果是最后一个页面,则退出浏览器):driver.close();退出浏览器:driver.quit()

# 最大化窗口
driver.maximize_window()
# 关闭当前页面(如果是最后一个页面,则退出浏览器)
driver.close()
# 退出浏览器
driver.quit()

9、获取网页中的元素:查找单个元素(通用方法、特定方法)、查找多个元素(通用方法、特定方法

# 查找单个元素
# 通用查找方法,by参数指定查找类型,value参数指定查找值
# By.ID
# By.CLASS_NAME
# By.XPATH
# By.CSS_SELECTOR
# By.LINK_TEXT
# By.PARTIAL_LINK_TEXT
# By.NAME
# By.TAG_NAME
# 导入By模块
from selenium.webdriver.common.by import By

element=driver.find_element(by=By.ID,value='id')
# 特定查找方法
element = driver.find_element_by_id('id')
element=driver.find_element_by_class_name('class')
element=driver.find_element_by_xpath('xpath')
element=driver.find_element_by_css_selector('css_selector')
element=driver.find_element_by_link_text('link_text')                   # 通过完整链接定位
element=driver.find_element_by_partial_link_text('partial_link_text')   # 通过部分链接定位
element=driver.find_element_by_name('name')         # 通过元素name标记定位
element=driver.find_element_by_tag_name('tag_name') # 通过元素名称定位

# 查找多个元素(同上,返回list)
# 通用查找方法
elements=driver.find_elements(by=By.XPATH,value='xpath')
# 特定查找方法
elements=driver.find_elements_by_id('id')

10、元素的方法:1、清空输入框中的内容:element.clear() ;2、模拟向输入框输入文字:element.send_keys('Python');

        3、模拟按下回车键:element.send_keys(Keys.RETURN);4、模拟点击(要求element为可点击按钮:element.click()

# 清空输入框中的内容
element.clear()
# 模拟向输入框输入文字
element.send_keys('Python')
# 模拟按下回车键
element.send_keys(Keys.RETURN)
# 模拟点击(要求element为可点击按钮)
element.click()

11、处理弹窗:driver.switch_to.alert,alert适用于其他情况:切换新开的窗口:window(current_windows[1]);切换网页中嵌套的另一个网页:frame()等;实现过程一样

# 处理弹窗
alert_ele=driver.switch_to.alert
alert_ele.dismiss()

12、拖拽元素ActionChains(动作链)

# 拖拽元素ActionChains(动作链)
source_element=driver.find_element(By.ID,'id')
target_element=driver.find_element(By.ID,'id')
action_chains=ActionChains(driver)
action_chains.drag_and_drop(source=source_element,target=target_element).perform()

13、页面时间:1、页面加载时间:driver.set_page_load_timeout(time/s);2、页面的等待时间:

# 设置页面加载超时时间,单位:秒
driver.set_page_load_timeout(30)

# 处理加载页面时的等待
# 方式一:执行命令等待的最长时间,单位:秒
driver.implicitly_wait(5)
# 方式二:休眠线程
import time
time.sleep(5)
# 方式三:显式等待
try:
    element=WebDriverWait(driver,timeout=10).until(
        EC.presence_of_all_elements_located((By.ID,'id'))
    )
finally:
    driver.quit()

注:1、方式三:显式等待中的 until或until_not 中的可执行方法method参数,method参数一定要是可以调用的,即这个对象一定有 call() 方法,否则会抛出异常:TypeError: 'xxx' object is not callable;但是element对象不是!

  2、需要导入'EC'模块:from selenium.webdriver.support import expected_conditions as EC

14、导入容错的模块:exceptions

from selenium.common import exceptions
try:
    driver.get('https://www.baidu.com/')
except exceptions.TimeoutException as err:
    print(err,'请求超时')

 15、执行JS脚本:driver.execute_script( )

# 执行JS脚本
js='window.scrollTo(0,document.body.scrollHeight);'  # 滚动到页面底部
driver.execute_script(js)
time.sleep(3)

 注:1、window.scrollTo:JS控制滚动条的位置:(0,0):滚动到页面顶部;(0,document.body.scrollHeight):滚动到页面底部

posted @ 2019-12-10 07:56  石斛  阅读(246)  评论(0编辑  收藏  举报