zoukankan      html  css  js  c++  java
  • 爬虫(2)——requests以及xpath的使用

    一、requests

    requests.request(method,url,**kwargs)
    
    # 常见参数
    # params/data/json  上传数据
    # files  上传文件
    # headers/cookies
    # proxies 
    # auth  授权

    1、get请求

    response = requests.get(url)

    1)定制参数

    参数使用params传递,注意:不需要urlencode

    data = {"wd": “北京”}
    response = request.get(url, params=data)

    2)获取网站源码

    response.text

    3)访问或定制的编码

    response.encoding = 'utf-8'

    4)获取请求的url

    response.url 获取请求的url

    5)响应的字节类型

    response.content

    6)响应的状态码

    response.status_code

    7)响应的头信息

    response.headers

    8)获取json数据

    response.json()  # 反序列化,将json数据转换为python中的列表或字典

    2、post请求

    response = requests.post(uri, data=data) #data上传的参数无需urlencode

    3、headers定制

    同urllib.request的头定制

    ua可以使用第三方包

    from fake_useragent import UserAgent
    
    ua = UserAgent().random

    4、proxy定制

    在请求中设置proxies参数,参数类型是一个字典类型

    import requests
    
    from fake_useragent import UserAgent
    
    url = 'http://www.baidu.com/s'
    
    headers = {
        'user-agent': UserAgent().random
    }
    data = {
        'wd':'ip'
      }
    proxy = {
        'http':'219.149.59.250:9797'
    }
    r = requests.get(url=url,params=data,headers=headers,proxies=proxy)
    
    with open('proxy.html','w',encoding='utf-8') as fp:
        fp.write(r.text)

    5、cookie定制

    s = requests.session()

    1)方法

    s.get()  
    s.post()
    s.put()
    s.delete()
    s.patch()
    s.close()  # 关闭会话
    s.cookies  # 获取cookies  

    二、xpath

    1、xpath语法

    XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。

    1)路径查询

    / 查找子节点,HTML中从<html>开始的  /html/title/text()

    // 查找所有子孙节点,不考虑层级关系 如://title/text()

    ./a/@href 当前路径下的a元素的href属性,如/html -> Element , ./title/text()

    ../span/text() 父级下的span的文本内容

    扩展:使用*通配符 /* 任意一个子节点,//*任意一个孙子节点

    2)谓词查询

    //div[@id] 查找所有包含id属性的div节点

    //div[@id="maincontent"]  查询id属性为maincontent的div的标签

    3)属性查询

    //@class 查询带有class属性的所有标签

    4)逻辑运算

    //div[@id="head" and @class="s_down"] 查找所有id属性等于head并且class属性等于s_down的div标签 (多个条件,and且的关系,or或的关系)

    //title | //price 同时获取title和price两个标签,| 前后的两个是完整且独立的xpath路径

    5)模糊查询

    //div[contains(@id, "he")]  查询所有id属性中包含he的div标签

    //div[starts-with(@id, "he")]  查询所有id属性中包以he开头的div标签

    //div[ends-with(@id, "he")]  查询所有id属性中包以he结尾的div标签

    //ul/li[last()]/a/@href  ul中最后一个li内的a元素的href属性值

    6)内容查询

    //div/h1/text() 查找所有div标签下的直接子节点h1的内容

    2、xpath使用

    1)安装lxml库

    pip install lxml 

    2)安装xpath插件(调试方便,非必须)

    chrome 安装xpath helper,ctrl+shift+x 打开控制台,Shift+选择网页内容

    3)导入lxml.etree

    from lxml import etree

    4)etree.parse()

    html_tree = etree.parse('XX.html')  # 解析本地html文件

    5)etree.HTML()

    html_tree = etree.HTML(rsponse.read().decode('utf-8')  # 解析网络的html字符串

    6)html_tree.xpath()

    xpath()返回是一个list列表

    xpath返回的Element,可以看成是一个字典

    三、爬取古诗文网

    1、获取古诗文网推荐页所有的诗词

    import os
    import time
    from csv import DictWriter
    from random import random
    
    import requests
    from lxml import etree
    
    from fake_useragent import UserAgent
    
    
    has_header = os.path.exists("gushiwen.csv")  # 是否第一次写入csv的头
    header_fields = ('title', 'author', 'content')
    
    
    def itemipeline4csv(item): # 保存数据
        global has_header
        with open('gushiwen.csv', 'a') as f:
            writer = DictWriter(f, header_fields)
            if not has_header:
                writer.writeheader()  # 写入第一行标题
                has_header = True
    
            writer.writerow(item)  # 写入数据
    
    
    
    def parse(html):
        root = etree.HTML(html)
        divs = root.xpath("//div[@class='left']/div[@class='sons']")
        item = {}
        for div in divs:
            item["title"] = div.xpath(".//p[1]//text()")[0]
            item["author"] = " ".join(div.xpath(".//p[2]/a/text()"))
            item["content"] = div.xpath(".//div[@class='contson']//text()")
            itemipeline4csv(item)
    
    
    def get(url):
        resp = requests.get(url, headers={'User-Agent': UserAgent().random})
        if resp.status_code == 200:
            parse(resp.text)
        else:
            raise Exception("请求失败")
    
    
    if __name__ == '__main__':
        for i in range(1, 11):
            time.sleep(random())
            get("https://www.gushiwen.org/default_%s.aspx" % i)
     

    2、通过登录,获取收藏的古诗文

    补充:云打码使用了超级鹰第三方,注册账号重置,简单的修改,最后调用read_code()方法获取验证码的字符串

    import requests
    from hashlib import md5
    
    class Chaojiying_Client(object):
    
        def __init__(self, username, password, soft_id):
            self.username = username
            password =  password.encode('utf8')
            self.password = md5(password).hexdigest()
            self.soft_id = soft_id
            self.base_params = {
                'user': self.username,
                'pass2': self.password,
                'softid': self.soft_id,
            }
            self.headers = {
                'Connection': 'Keep-Alive',
                'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
            }
    
        def PostPic(self, im, codetype):
            """
            im: 图片字节
            codetype: 题目类型 参考 http://www.chaojiying.com/price.html
            """
            params = {
                'codetype': codetype,
            }
            params.update(self.base_params)
            files = {'userfile': ('ccc.jpg', im)}
            r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
            return r.json()
    
        def ReportError(self, im_id):
            """
            im_id:报错题目的图片ID
            """
            params = {
                'id': im_id,
            }
            params.update(self.base_params)
            r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
            return r.json()
    
    
    def read_code(filename):
        chaojiying = Chaojiying_Client('huiyichanmian', 'christian825', '903878')  # 用户中心>>软件ID 生成一个替换 96001
        im = open(filename, 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
        ret = chaojiying.PostPic(im, 8001)
        return ret['pic_str']
    超级鹰接口代码
    """
    1、下载验证码的图片
    2、图片验证码的打码
    3、登录
    4、获取个人的收藏信息
    """
    import requests
    
    
    from lxml import etree
    from fake_useragent import UserAgent
    
    
    # 创建一个session对象
    from day2.chaojiying import read_code
    
    session = requests.session()  # 获取验证码的接口和登录的接口必须在同一个session中请求
    
    
    def download_code():
        resp = session.get('https://so.gushiwen.org/RandCode.ashx', headers={'User-Agent': UserAgent(verify_ssl=False).random})
        with open("code.png", 'wb') as f:
            f.write(resp.content)
    
    
    def get_code_str():
        download_code()
        return read_code("code.png")
    
    
    def login():
        resp = session.post("https://so.gushiwen.org/user/login.aspx",
             data={
                 'email': 'huiyichanmian@yeah.net',
                 'pwd': 'christian825',
                 'code': get_code_str()
             })
        if resp.status_code == 200:
            collect()
        else:
            print("-"*30)
            print(resp.text)
    
    
    def collect():
        resp = session.get('https://so.gushiwen.org/user/collect.aspx')
        parse(resp.text)
    
    
    def parse(html):
        root = etree.HTML(html)
        divs = root.xpath("//div[@class='left']/div[@class='sons']")
        item = {}
        for div in divs:
            item["title"] = div.xpath(".//p[1]//text()")[0]
            item["author"] = " ".join(div.xpath(".//p[2]/a/text()"))
            item["content"] = div.xpath(".//div[@class='contson']//text()")
            print(item)
    
    
    if __name__ == '__main__':
        login()
  • 相关阅读:
    516. 最长回文子序列
    NC50493 环形石子合并
    NC16650 采药
    NC16664 合唱队形
    NC51170 石子合并
    148. 合并果子
    NC25138 子串查询
    二维数组对角线 的 规律
    如何讲一个网页转换为jpg?(图片!)
    Java两倍 犯错题
  • 原文地址:https://www.cnblogs.com/huiyichanmian/p/12456691.html
Copyright © 2011-2022 走看看