zoukankan      html  css  js  c++  java
  • 脚本编写相关的Python库

    Requests库

    requests.request(method, url, **kwargs)是最基本的方法,其它方法封装内部大多为request

    我们通常用r = requests.get(url)获取网页信息,其会构造一个向服务器请求资源的Request对象,对象由Requests库内部生成;get()函数返回的内容表示为rr是一个Response对象,包含从服务器返回的所有相关资源。

    完整方法:requests.get(url, params=None, **kwargs),其中,url为链接,params是字典或字节流格式,**kwargs是12个控制访问的参数。

    request参数(使用时写成r.request.params等):

    • params:字典或字节序列,作为参数增加到url中
    • data:字典、字节序列或文件对象,作为Request的内容
    • json:JSON格式的数据,作为Request的内容
    • headers:字典,HTTP定制头
    • files:字典类型,传输文件
    • timeout:设定超时时间(单位:秒)
    • proxies:字典类型,设定访问代理服务器,可以增加登录认证
    • allow_redirects:True/False,默认为True,重定向开关
    • stream:True/False,默认为True,获取内容立即下载开关
    • verify:True/False,默认为True,认证SSL证书开关
    • cert:本地SSL证书路径
    • cookies:字典或CookieJar,Request中的cookie
    • auth:元组,支持HTTP认证功能

    response对象:

    r.status_code:状态码,状态码为200表示访问成功,否则(比如404)表示访问失败。

    r.headers:头部信息

    r.text:url的页面内容

    r.content:url相应内容的二进制形式

    r.encoding:从HTTP header中猜测的响应内容编码方式(如果header中不存在charset,则认为编码为ISO-8859-1)

    r.apparent_encoding:从内容中分析出的相应内容编码方式(备选方式)(一般更加准确)

    r.raise_for_status():如果状态码不是200,则产生异常requests.HTTPError(如404表示失败)

    爬取网页的通用代码框架:

    import requests
    
    def getHTMLText(url):
        try:
            r = requests.get(rul, timeout = 30)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return "ERROR"
    
    if __name__ = "__main__":
        url = "http://www.baidu.com"
        print(getHTMLText(url))
    

    HTTP协议

    HTTP,Hypertext Transfer Protocol,超文本传输协议

    HTTP协议采用URL作为定位网络资源的标识。

    URL格式:http://host[:port][path]

    • host:合法的Internet主机域名或IP地址
    • port:端口号(默认为80)
    • path:资源路径

    其它方法:

    requests.head():获取HTML网页头信息(可以用r.headers获取头部信息的内容,但是不能使用r.text

    requests.post(url, data = [content]):向HTML网页提交POST请求,附加新的数据

    requests.put(url, data = [content]):向HTML网页提交PUT请求,与POST使用类似,不过功能是覆盖原URL位置的资源

    requests.patch():向HTML网页提交局部修改请求

    requests.delete():向HTML网页提交删除请求

    Robots协议:

    网站的robots协议一般放在根目录,如http://www.baidu.com/robots.txt

    基本语法:

    #注释:*表示所有,/表示根目录
    User-agent: * (表示限制哪些爬虫)
    Disallow: / (表示不允许访问的目录)
    

    修改user-agent:

    网站可能通过对网站访问的HTTP的头来判断访问是否由爬虫引起,但是我们可以更改头部信息,即修改r.request.headers(如r = requests.get(url, headers = {'user-agent': 'Mozilla/5.0'}))来进行访问。

    搜索引擎关键字接口:

    比如:http://www.baidu.com/s?wd=keyword、http://www.so.com/s?q=keyword

    我们把信息加在params里即可:

    import requests
    kv = {'wd': 'Python'}
    kv1 = {'user-agent': 'Mozilla/5.0'}
    r = requests.get("http://www.baidu.com/s?ie=UTF-8", params = kv, headers = kv1)
    print(r.request.url)
    

    输出的结果:

    https://www.baidu.com/s?ie=UTF-8&wd=Python
    

    爬取图片:

    import requests
    import os
    root = "D://pics/"
    url = "https://tva4.sinaimg.cn/large/0072Vf1pgy1foenqvqwvqj31hc0xc7aj.jpg"
    path = root + url.split('/')[-1] #命名为网站上的原文件名,即最后一个'/'的后面的内容
    if not os.path.exists(root):
    	os.mkdir(root)
    if not os.path.exists(path):
    	r = requests.get(url)
    	with open(path, 'wb') as f:#打开文件,定义为标识符f
    		f.write(r.content)##content为二进制内容
    		f.close()
    		print("Picture Saved Successfully!")
    else:
    	print("Picture Exists already!")
    

    (视频和音频也是一样的)

    信息标记和提取

    三种信息标记:

    XML(eXtensible Markup Language)(用于Internet上的信息交互):<name ...> ... </name><name ... /><!--...-->

    JSON(JavaScript Object Notation)(用于移动应用云端和节点的信息通信,无注释):形式为键值对。如果一个键对应多个值,用[]括起来;如果有嵌套,用{}括起来。

    (例:"key": "value""key": ["value1", "value2"]"key": {"subkey": "subvalue"}

    YMAL(YAML Ain't Markup Language)(用于系统配置文件,易读、有注释):形式为无类型键值对,即key: value,用缩进表示所属关系,如:

    name:
    	newname: name1
    	oldname: name2
    

    -表示并列关系,如:

    name:
    - name1
    - name2
    

    #进行注释,用|表达大段数据。

    提取信息的一般方法:

    • 完整解析信息的标记形式,再提取关键信息(BeautifulSoup库)
    • 直接搜索关键信息(Re库)

    Beautiful Soup库

    ~是解析html和xml文件的功能库。

    引用:from bs4 import BeautifulSoup(简写为bs4,导入BeautifulSoup这个类)(注意大写)

    解析:soup = BeautifulSoup(r.text, "html.parser")即解析后的内容(会转成UTF-8)

    (或者soup2 = BeautifulSoup(open("D://a.html"), "html.parser")

    soup.prettify()可返回排版后的文件内容)

    其它解析器:

    lxml的HTML解析器:BeautifulSoup(mk, 'lxml')

    lxml的XML解析器:BeautifulSoup(mk, 'xml')

    以上两个都需要pip install lxml

    html5lib的解析器:BeautifulSoup(mk, 'html5lib')

    需要pip install html5lib

    HTML代码是tag组成的树形结构,用<tag>...</tag>括起来。

    soup.<tag>可以调用<tag>的内容,如soup.title,可以返回<title>TITLE_CONTENT</title>

    如果存在相同名字的tag时,用soup.<tag>只能返回第一个。

    <tag>.parent可以调用上一层tag,<tag>.name可以得到tag名字,如:

    soup.a.name(就是a)

    soup.a.parent.namesoup.a.parent.parent.name:a的祖先tag的名字

    soup.attrs获取tag的属性信息(字典类型)

    soup.string表示尖括号之间的内容(类型为bs4.element.NevigableString

    在HTML代码中,<p><!...!></p>表示注释,而我们调用soup.p.string时,会得到注释的内容,而且和上面不同的是,注释的类型是bs4.element.Comment,所以我们可以通过string的类型判断这一段是不是注释。

    tag树的遍历:

    tag.contents:子节点的列表(也包含字符串节点,比如' '换行酱紫的,用isinstance(tag, bs4.element.Tag)进行判断(需要直接import bs4))

    tag.children:子节点的迭代类型

    tag.descendants:子孙节点的迭代类型

    tag.parent:父节点(如果没有就是None

    tag.parents:祖先节点的迭代类型

    tag.next_sibling:按照HTML文本顺序的下一个兄弟节点

    tag.previous_sibling:按照HTML文本顺序的上一个兄弟节点

    tag.next_siblings:按照HTML文本顺序的后面的所有兄弟节点的迭代类型

    tag.previous_siblings:按照HTML文本顺序的前面的所有兄弟节点的迭代类型

    tag.find_all(name, attrs, recursive, string, **kwargs):查找,返回列表

    name为检索的tag名字;如果要查找多种tag,可以传入一个列表;如果给出的标签名称是True,那么会返回所有标签信息;如果我们要求查找“**开头的tag”,可以利用re库。

    attrs限制属性,可以查找属性值,也可以查找键值对,比如:soup.find_all('p', 'xxx')或者soup.find_all(att = 'xxx')

    recursive:是否检索全部子孙,默认为TrueFalse即只检索子节点)。

    string指对<>...</>中间区域进行字符串检索(返回的只有中间的字符串的列表)。

    简写:tag.find_all(...)可简写作tag(...)soup.find_all(...)也可以简写作soup(...)

    扩展:

    <>.find():只返回一个结果

    <>.find_parents():在祖先节点中查找,列表类型

    <>.find_parent():在祖先节点中查找,只返回一个结果

    find_next_siblings()find_next_sibling()find_previous_siblings()find_previous_sibling()同理。

    Re库

    RE(Regular Expression):正则表达式

    正则表达式语法:

    • .:表示任何字符

    • []:字符集,[abc]表示a、b、c;[a-z]表示所有小写字母

    • [^]:非字符集,[^abc]表示非a、b、c的所有字符

    • *:前一个字符零次或多次扩展,如abc*表示ababcabcc……

    • +:前一个字符一次或更多次数的扩展,如abc+表示abcabcc……

    • ?:前一个字符零次或一次扩展,如abc?表示ababc

    • |:左右表达式任意一个,如abc|def表示abcdef

    • {m}:前一个字符的m次扩展,ab{2}c表示abbc

    • {m,n}:前一个字符的m~n次扩展,ab{1,2}c表示abcabbc

    • ^:匹配字符串开头

    • $:匹配字符串结尾

    • ():分组标记,内部只能使用|

    • d:等价于[0-9]

    • w:等价于[A-Za-z0-9]

    应用:

    • 字母组成的字符串:^[A-Za-z]+$

    • 0~255的数字:([1-9]?d|1d{2}|2[0-4]d|25[0-5])

      (0-99|100-199|200-249|250-255)

    正则表达式的表示类型是raw string(即不包含转义符的字符串),表示为r'text'

    常用函数:

    • re.search(RawString, String, flags = 0):在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

      flags为控制标记,常用标记有:

      • re.I:忽略大小写
      • re.M^允许把每行的开头作为匹配的开始位置
      • re.S.能匹配任意字符(原本不能匹配换行符)
    • re.match(RawString, String, flags = 0):在一个字符串的开始位置起匹配正则表达式,返回match对象

    • re.findall(RawString, String, flags = 0):以列表形式返回所有匹配的字符串

    • re.split(RawString, String, maxsplit = 0, flags = 0):将字符串按正则表达式匹配结果进行分割,将匹配的部分去掉,返回列表(maxsplit表示最大分割数,剩余部分作为最后一个元素输出)

    • re.finditer(RawString, String, flags = 0):返回一个匹配结果的迭代类型,迭代元素为match对象

    • re.sub(RawString, repl, String, count = 0, flags = 0):将所有匹配的子串替换,返回替换后的子串(repl表示替换字符串,count表示最大替换次数)

    match对象的属性:

    • .string:String
    • .re:RawString
    • .pos:正则表达式搜索文本的开始位置
    • .endpos:正则表达式搜索文本的结束位置

    match对象的方法:

    • .group(0):匹配后的字符串(留坑:group(1)group(2)
    • .start():匹配字符串在原始字符串的开始位置
    • .end():匹配字符串在原始字符串的结束位置
    • span()(.start(), .end())

    贪婪匹配&最小匹配:

    Re库默认采用贪婪匹配,即输出匹配最长的子串。

    如果要求得到最短的子串,需要对符号做如下修改:

    • *?:0次或多次扩展,取匹配的最小次数
    • +?:1次或多次扩展,取匹配的最小次数
    • ??:0次或1次扩展,取匹配的最小次数
    • {m, n}?:m次到n次扩展,取匹配的最小次数

    两种写法:

    • 函数式写法:rst = re.search(r'...', '...')
    • 面向对象写法:pat = re.compile(r'...') rst = pat.search('...')

    re.compile(r'...', flags = 0)可以将正则表达式的原生字符串形式编译成re对象,以上六种函数都可以直接用于re对象。

    Selenium库

    参考:

    安装

    pip install selenium
    

    在https://chromedriver.storage.googleapis.com/index.html找到对应版本的chromedriver丢到chrome.exe所在文件夹。

    (写代码的时候不要把文件命名为selenium.py!会出现ImportError: cannot import name webdriver

    使用

    大致框架

    • 预备:
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    driver = webdriver.Chrome('C:Program FilesGoogleChromeApplicationchromedriver.exe')
    

    selenium.webdriver提供WebDriver的实现,Keys提供案件支持,如RETURNF1ALT

    如果不给chromedriver.exe配置环境变量,就直接写绝对路径。

    • 加载网页:
    driver.get("http://www.python.org")
    

    ……中间部分搞一些大新闻

    • 关闭网页(关闭一个标签页)
    driver.close()
    

    交互方式

    如果想定位到一个可以输入的文本框,可以先在浏览器中检查网页的elements,找到对应位置的信息。

    比如北航CAS登录页面的密码框的信息:

    <input type="password" placeholder="请输入密码" i18n="login.form.password.placeholder" id="pwPassword" name="password">
    

    可以这样定位:

    elem = driver.find_element_by_id("pwPassword")
    

    其它定位方式:

    find_element_by_id
    find_element_by_name
    find_element_by_xpath #见下
    find_element_by_link_text #见下
    find_element_by_partial_link_text
    find_element_by_tag_name #即查找HTML标签名
    find_element_by_class_name #即查找class
    find_element_by_css_selector #待填坑
    

    (如果查找多个元素,改成elements即可,返回列表类型)

    关于XPATH:

    举例:

    <html>
      <body>
           <form id="loginForm">
                <input name="username" type="text" />
    			<input name="password" type="password" />
    			<input name="continue" type="submit" value="Login" />
    			<input name="continue" type="button" value="Clear" />
    		</form>
    	</body>
    <html>
    

    三种查找form的方法:

    login_form = driver.find_element_by_xpath("/html/body/form[1]") #绝对路径
    login_form = driver.find_element_by_xpath("//form[1]") #页面中第一个form元素
    login_form = driver.find_element_by_xpath("//form[@id='loginForm']") #id为loginForm的form元素
    

    三种查找username的方法:

    username = driver.find_element_by_xpath("//form[input/@name='username']") #第一个form中name为username的input元素
    username = driver.find_element_by_xpath("//form[@id='loginForm']/input[1]") #id为loginForm的form元素的第一个input元素
    username = driver.find_element_by_xpath("//input[@name='username']") #第一个name属性是username的input元素
    

    两种获取Clear按钮的方法:

    clear_button = driver.find_element_by_xpath("//input[@name='continue'][@type='button']") #name是continue,type是button的input元素
    clear_button = driver.find_element_by_xpath("//form[@id='loginForm']/input[4]") #id是loginForm的form元素的第四个input元素
    

    关于通过链接文本获取超链接:

    link = driver.find_element_by_link_text('Content')
    link = driver.find_element_by_partial_link_text('PartialContent') #部分内容查找
    

    模拟键盘:

    elem.clear():将文本框清空

    elem.send_keys("xxxxxxx"):输入

    elem.send_keys(Keys.RETURN):回车

    下拉选择框:

    from selenium.webdriver.support.ui import Select
    select = Select(driver.find_element_by_name('name'))
    select.select_by_index(index)
    select.select_by_visible_text("text")
    select.select_by_value(value)
    

    取消选择:

    select = Select(driver.find_element_by_id('id'))
    select.deselect_all()
    

    点击按钮:

    driver.find_element_by_id("submit").click()
    

    弹出对话框:

    alert = driver.switch_to_alert()
    alert.accept()
    alert.dismiss()
    
  • 相关阅读:
    nginx+vue+thinkphp5.1部署,解决前端刷新404,以及前端404解决后,后台又404的问题
    centos7.4挂载硬盘
    thinkphp5.1+layui2.x 时间戳转换为日期格式
    解决linux(ubuntu18)下无法挂载ntfs磁盘,并读写挂载硬盘
    sublime中nodejs配置
    jquery 中的$("obj").html('')中的html动态改变之后点击事件失效
    js怎么弹出变量的数据类型
    异步操作执行后子页面重新修改父页面iframe高度
    iframe标签父页面高度自适应
    string.Format()方法、Graphics类、DrawImage方法
  • 原文地址:https://www.cnblogs.com/Hany01/p/python-script.html
Copyright © 2011-2022 走看看