python爬虫知识深度巩固

不适合初学的,这个是小编的知识巩固杂记

 

1、AJAX

2、动态渲染页面

3、节点交互,点击、输入、清除;

    动作链:from selenium.webdriver import ActionChains

4、执行JavaScript

5、获取节点信息

6、选项卡管理

7、Splash的使用

8、splash支持异步处理:

9、splash对象属性

10、splash对象的方法

splash api的调用:

11、splash负载均衡

12、selenium抓取淘宝商品

13、代理设置

selenium设置代理

14、cookies池搭建

15、APP的爬取

16、Charles的使用

17、APPium的基本使用


1、AJAX

AJAX原理:Asynchronous JavaScript and XML,即异步的JavaScript和XML,利用JavaScript在保证页面不被刷新、页面不改变的情况下与服务器交换数据更新部分网页。

发送AJAX请求到网页更新步骤:发送请求、解析内容、渲染网页

发送请求的JavaScript代码:

var xmlhttp;
if  (window.XMLHttpRequest)  {
II  code  for  IE7+,  Firefox,  Chrome,  Opera,  Safari
xmlhttp=new  XMLHttpRequest();
} else  {II  code  for  IE6,  IES
xmlhttp=new  ActiveXObject (” Microsoft.XMLHTTP ”);
}
xmlhttp.  onreadystatechange=function() {
  if  (xmlhttp.ready5tate == 4  &&  xmlhttp.status==200)  {
       document.getElementById(“myDiv”).innerHTML=xmlhttp.responseText;将di为myDiv的节点内部的HTML代码更改为服务器返回的内容
  }
}

xmlhttp.open(“post”,“/ajax/”,true);

xmlhttp.send();这是JavaScript对ajax最底层的实现,实际上是新建了xmlhttprequest对象,然后调用onreadystatechange属性设置监听,然后调用post、send方法向某个链接发送请求。

AJAX其实有其特殊的请求类型,叫作xhr。实例中request headers中一个信息为:x-requested-with:xmlhttprequest此标记显示请求为ajax请求。

2、动态渲染页面

JavaScript动态渲染页面不只ajax一种。

模拟浏览器的库:selenium、splash、PyV8、Ghost等

selenium中获取单个节点的方法by_id、name、xpath、link_text、partial_link_text、tag_name、class_name、css_selector

find_element(By.ID,id);获取多个节点find_elements

3、节点交互,点击、输入、清除;

    动作链:from selenium.webdriver import ActionChains

     source =browser.find_element_by_css  selector('#draggable ' )
     target=  browser.find_element_by_css_selector('#droppable' )
     actions = ActionChains(browser)
     actions.drag_and_drop(source,  target)
     actions. perform()

4、执行JavaScript

      使用execute_script()

       browser. execute_script('window.scrollTo(o,  document.body. scrollHeight )’)
       browser. execute_script( 'ale rt (” To  Bottom ”)')

5、获取节点信息

 

获取属性get.attribute,比如class的获取:logo.get_attribute (’ class ' );获取文本值用text;获取id、位置、标签名、大小

切换frame:switch_to.frame切换

延时等待:隐式等待implicitly_wait;显式等待from  selenium.webdriver.support.ui  import WebDriverWait
from selenium.webdriver.support import expec te d _c onditions  as  EC
browser = webdriver.Chrome()
browser.get (’ https://www.taobao.com /’)
wait  = WebDriverWait(browser, 10)
input  =  wait.  until(EC.  presence_of _element_located(  (By.ID ,’ q ’)))

可进行cookies添加、删除、获取

6、选项卡管理

browser.execute_script (’ window.open ()’)
print( browser.window _handles)
browser.switch_to_window(browser.window_handles[l])

7、Splash的使用

splash是一个JavaScript渲染服务,带有http api的轻量级浏览器。

可实现功能:异步方式处理多个网页渲染过程;获取渲染后的页面的源码或截图;通过关闭图片渲染或者使用adblock规则加快页面渲染速度;可执行特定JavaScript脚本;通过lua脚本来控制页面渲染过程;获取渲染的详细过程并通过har格式呈现。

splash执行整个网页渲染过程

function main(splash, args)
       assert(splash:go(args. url) )
       assert(splash:wait(o.s))
       return {
            html= splash :h tml(),
            png  = splash:png(),
            har = splash:  har(),
        }

end通过lua语言脚本加载页面,最后返回网页源码、截图、har信息。

8、splash支持异步处理:

function main(splash,  args)
local  example_urls =  {"url1","url2","url3"}
local  urls  = args . urls  or  example_urls
local  results  =  {}
for  index,  url  in  ipairs(urls)  do
local  ok , reason = splash:go (” http ://” ..  url )
if ok then
splash:wait(2)
results[url]  = splash:png()
end
end
return  results
end

9、splash对象属性

main方法的第一个参数是splash,类似于selenium中的webdriver

args:可以获取加载时配置的参数,若为url,get请求,可以获得get请求参数,post同理。

function main(splash, args)
local url  =  args.url
end等价于  function main(splash)

local url=splash.args.url
end

js_enabled:这个属性是splash执行JavaScript的开关

function main(splash, args)
splash:go( ” url” )
splash. js _e nabled =  false
local  title  =  splash:evaljs (” document.title")
return  {title=title}
end

resource_timeout:可以设置加载超时时间

images_enabled:设置图片是否加载,禁止图片可能会影响JavaScript渲染

plugins_enabled:控制浏览器插件是否开启

scroll_position:控制页面上下或左右浮动

function main(splash, args)
assert(splash:go('https://www.taobao.com ’))
splash.scroll_position  =  {y=400}
return {png=splash: png()}

end控制页面向下浮动400像素值

10、splash对象的方法

go:请求链接

ok, reason = splash:go{url,  baseurl=nil,  headers=nil, http_method=" GET",  body=nil, formdata=nil}

wait:控制页面等待时间

ok, reason =  splash:wait{time,  cancel_on_redirect=false,  cancel_on_error=true}

jsfunc:直接调用JavaScript定义的方法

function main( s p l a s h , args)
local  get_div_count =  splash : jsfunc([[
function ()  {
}
]])
var  body  = document.body;
var  divs  =  body .getElementsByTagName (’ div');
return  divs.length;
splash:go (” https://vrww.baidu. com ”)
return  (” There  are  %s  DIVs"):forma(
get_div  _count())
end

evaljs:可以执行JavaScript代码并返回最后一条JavaScript语句的返回结果

result=splash:evaljs(js)

local title=splash:evaljs(“document.title”)

runjs:可以执行JavaScript代码

autoload:可以设置每个页面访问时候自动加载的对象

ok , reason = splash: au toload{source_or_url, source=nil, url=nil}

call_later:通过设置定时任务和延迟时间来实现任务延时执行

http_get:模拟发送http的get请求

response =  sp lash:http_get{url,  headers=nil, follow_re dir ects=true}

http_post:response =  splash:http_post{url,  h e a d e r s = 「 1 i l , follow_redirects=true, body=nil}

set_content:设置页面的内容;html:获取网页源码;png、jpeg获取网页截图har:获取页面加载过程描述;url:获取当前网页网址;get/add/clear_cookies:获取当前页面cookies;get/set_viewport_size获取/设置当前浏览器页面的大小;set_view_full:全屏显示;set_user_agent:设置浏览器头;set_custom_headers设置请求头。

select选择符合条件的第一个节点;select_all选择符合条件的所有节点;mouse_click模拟鼠标点击工作,传入的参数为x、y,也可直接选择某个节点;

splash api的调用:

render.html用于获取JavaScript渲染的页面的HTML代码

import requests
url  = ’ http://localhost:8050/render.html?url=https://www.baidu.com&wait=5'增加等待时间
response = requests . get(url)
print(response.text)可以获得页面渲染后的源代码

render.png/jpeg示例:

import  requests
url=“http : //localhost :80SO/render.png?url=https://www. taobao.com&wait=S&width=lOOO&height=700”
response =  requests.get(url)
with  open (’ taobao.p ng ’, t  wb  ’)  as  f:
f . write(response.content)

render.har获取页面加载的har数据

render.json此接口包含了前面接口的所有功能 

http:/ /localhost:8050/render.json?url= htt ps: //htt pbin.org&html =l&har=l

execute最强大的接口,可实现交互操作

import requests
from  urllib.parse  import quote
lua='''

function main(splash)

return "hello"
end

'''lua脚本
url  =’ http : //localhost:8050/execute?l ua_source =’+  quote(lua)
response =  requests.get(url)
print(response.text)

import requests
from  urllib.parse  import quote
lua ='''

fuction main(splash,  args)
local  treat  =  require (” treat ”)
local  response =  splash:http_get(" http: // httpbin . org/get ”)
return  {
html=treat.as_string(response.body),
url=response. url,
status=response.status

end

'''
url  =’ http://localhost:80SO/execute?l ua _source=' + quote(lua)
response =requests.get(url)
print(response.text)

11、splash负载均衡

选用任意一台带有公网IP的主机来配置负载均衡,装好Nginx,修改nginx.cnf:

http{
up stream splash {
least_conn;
server 41.159.  27 .  223:  8050;
server 41.159.  27.  221:  8050;
server 41.159.  27.  9:  8050;
server 41.  159  .117. 119:  8050;
}
server {
         listen  8050;
         location  I {
               proxy_pass  http: //s plash;
           }
      }
}

配置认证:splash是可以公开访问的,如果不让其公开访问,还可以配置认证,借助于Nginx,可以在server的location字段添加auth_basic和auth_basic_user_file

http{
up stream splash {
least_conn;
server 41.159.  27 .  223:  8050;
server 41.159.  27.  221:  8050;
server 41.159.  27.  9:  8050;
server 41.  159  .117. 119:  8050;
}
server {
         listen  8050;
         location  I {
               proxy_pass  http: //s plash;
               auth basic ” Restricted";
               auth basic  user_file  /etc/nginx/conf . d/ .htpasswd;
           }
      }
}

这里使用的用户名、密码放在/etc/nginx/conf.d,用htpassword命令创建

12、selenium抓取淘宝商品

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'.m-itemlist.items.item')))

chorme headless模式:chorme59版本已经支持headless模式,无界面模式,这样爬取的时候就不会弹出浏览器了。

chrome_options  =  webdriver.ChromeOptions()
chrome_options .add_argument('--headless ’)
browser  =  webdriver.Chrome(  chrome  options=chrome  _options)

13、代理设置

proxy_handler  =  ProxyHandler({
’ http ’:’ http://'  +proxy,
'https ’:’ https://'  + proxy
})

socks5类型:

import socks
import socket
from  urllib  import  request
from  urllib.error  import  URLError
socks .set_default_proxy(socks.SOCKSS ,’ 127.0.0 .1 ’, 9742)
socket .socket = socks.socksocket
try:
response =  request .urlopen (’ http: //httpb in.org /get ’)
print(response.read().decode('utf-8 ’))
except  URLError  as e:
print(e.reason)

selenium设置代理

from  selenium import webdriver
proxy=  127.0.0.1:9743
chrome_ options =  webdriver.ChromeOptions  ()
chrome_options.add_argument ('--proxy-server=http ://’+  proxy)
browser = webdri  ver.chorme(chorme_options=chorme_options)
browser.get (’ http://httpbin.org/get ' )

代理池维护:

' insert  into  %s  (%s)  values  (%s )’%  (table,  keys, values)万能数据存储

requests中的Session可以帮助我们维持一个会话,而且可以自动处理cookies;访问登录页面获取初始的cookies,提取authenticity_token。

14、cookies池搭建

在没有登录的情况下,也可访问部分网页。

搭建cookies池需要一些账号,需要redis库,py中的redis-py、requests、selenium、flask

cookies架构:存储模块、生成模块、检测模块、接口模块

15、APP的爬取

app的爬取相比web端爬取更加容易,反爬虫能力没有那么强,而且大多数以json形式传输的,解析更简单。

抓包软件:wireshark、filddler、charles、mitmproxy、anyproxy

16、Charles的使用

确保手机和PC在同一个局域网内,可以使用手机模拟器通过虚拟网络连接,也可为真机。设置手机代理为Charles的代理地址,访问互联网的数据包就会经charles再转发到数据包真实的服务器,服务器返回的数据包由charles转发回手机,charles起到中间人的作用,所有流量包都可以捕捉到。

charles会一直监听PC和手机发生的网络数据包,捕获到的数据包都会显示在左侧。

一定要提前设置好charles的代理并配置好ca证书。

overview选项卡显示了请求接口的url,响应状态、请求方式等;

contents选项卡查看请求和响应的详细信息;

jsontext选项卡可查看response的body信息;

charles可以将捕获到的请求加以修改并发送修改后的请求

mitmproxy的使用

mitmproxy的功能:拦截http和https请求和响应;保存http会话并进行分析;模拟客户端发起请求,模拟服务器端返回响应;利用反向代理将流量转发给指定的服务器;利用py对http请求和响应进行实时处理。

mitmdump的使用

mitmdump是mitmproxy的命令行接口

命令启动mitmproxy:mitmdump  -w  outfile截获的数据会被保存在outfile文件中;mitmdump  -s script.py这里指定当前处理脚本为script.py。

def  request  (flow)  :
flow.request .headers['User-Agent ’]  =  'MitmProxy ’
print(flow.request .headers)定义了一个request方法,参数为flow,其实是一个httpflow对象,通过request属性即可获取到当前请求对象。

mitmdump提供了专门的日志输出功能,可以设定不同级别以不同颜色输出结果。

from  mitmproxy import  ctx
def  request(flow):
flow. request .headers [’ User-Agent']='Mitmproxy'
ctx.log.info(str(flow.request.headers))
ctx.log.warn(str(flow .r equest .headers))
ctx.log .error(str(fl ow.request.headers))

 

def request(flow):
request  =  flow.request

info  =  ctx . log.info
info(request.url)
info(str(reque st.headers))
info(str(reque st .cookie s))
info(reque st .ho st)
info(request.method)
info(str(request.port))
info(request.scheme)

修改请求的url:

from mitmproxy  import  ctx
def  response(flow):
response  =  flow.response
info  =  ctx.log.info

mitmdump爬取“得到”app电子书信息

import json
from mitmproxy import ctx
def response(flow):

url  =’ https://dedao.ig e tget.com/v3/di s cover/booklist ’
if  flow.request.url.startswith(url) :
text=flow.response.text
data  =  json.loads(text)
books  =  data.get('  c ’ ) . get('list')
for  book  in books:
ctx.log.info(str(book))

17、APPium的基本使用

appium是一个跨平台移动端自动化测试工具,可以便捷地为ios和Android平台创建自动化测试用例。可以模拟app内部的各种操作。

启动appium服务,将Android手机通过数据线和运行appium的pc相连,同时打开usb调试功能,确保爬虫可以连接到手机。

测试连接情况:adb  devices  -1

用appium内置的驱动器打开app,点击appium中的start new session,配置启动app时的desired capability参数

用py驱动app的方法:

首先需要在代码中指定一个appium server

server  = ’ http: //localhost:  472 3/wd/hub ’

desired_caps={'platformName:'android',

                         'deviceName:'mi_note_pro',

                          'appPackage':'com.tencent.mm',

                           'appAcitivity':'.ui.LancherUI'}

新建一个session,类似点击appium内置驱动的start session按钮

from  appi um  import webdriver
from  sele nium.webdriver. su pport.ui  import WebDriverWait
driver  = webdri  ver.Remote  (server ,  desired_  caps)配置完成后运行,就可以启动微信app

点击登录ell  =  driver.  find_e lement_by_xpath (”/ hierarchy /an droid.widget.Framelayout/android.widget.Linearlayout/
android.widget.Framelayout/android.view.View/android . widget.Framelayout/android.widget . Linearlayout/
android.widget.Framelayout/android.widget . Relativelayout/android.widget .R el ative la yout/a ndro id.widget.
Button[l ]”)
ell .  click()

wait  = WebDriverWait(driver, 30)
login  =  wait . until(EC.presence_of_element_located((By.ID ,’ com .t encent . mm:id/cjk')))
log in.click()
phone = wait.  until(EC.  presence_of_element_ located(  (By. ID, ' com.  ten  cent.mm:id/h2)))
phone.set_text('18888888888')

API:Appiumpythonclient

配置desired capability参数

首先需要在代码中指定一个appium server

from  appium  import webdriver

server  = ’ http: //localhost:  472 3/wd/hub ’

desired_caps={'platformName:'android',

                         'deviceName:'mi_note_pro',

                          'appPackage':'com.tencent.mm',

                           'appAcitivity':'.ui.LancherUI'}

driver=webdriver.Rmote(server,desired_caps)

查找元素可以使用selenium来查找

el  =  driver.find_element_by_id (’ com .tencent.mm:id/cjk ’)

Android平台,可使用UIAutomator来进行元素选择

el  =  self .d river .find_element_by_android_uiautomator (’ new  UiSe l ector() .  description (” Animation ”)’)
els=  sel f.dr iver.find_elements_by_android uiautomator('new UiSelector() .clickable(true)')

IOS平台上,可使用UIAutomation来进行元素选择

el  = self.driver.find_element_by  _ios  _uiautomation(' . elements()  [0] ’)
els= self.driver.find_element_by  _ios  _uiautomation( ' .elements ()’)

点击:可以使用tap方法,模拟手指点击,可设置按时长短

tap(self,  positions,  duration=None)

屏幕拖动:scroll(self,orgin_el,destination_el)

swipe()模拟从A滑动到B

swipe(self,  start_x, start_y,  end_x, end_y,  duration=None)

flick方法模拟从A点快速滑动到B点:flick(self,  start_x, start_y,  end_x,  end_y)

拖拽:drag_and_drop(self,orgin_el,destination_el)

文本输入:set_text

el  = find_element_by_id (’ com.tencent.mm:id/cjk')

el.ste_text(‘hello’)

动作链:Touchaction支持tap、press、long_press、release、move_to、wait、cancel

el  =  self . driver.find_element_by_accessibility_id (’ Animation ' )
action  = TouchAction(self  .driver)
action.tap(el).perform()

你可能感兴趣的:(python爬虫知识深度巩固)