爬虫基础


"""
    目标:

    - pip install requests
    - pip install bs4
    - pip install lxml

    请确认安装依赖包:

    - pip install requests
    - pip install bs4
    - pip install lxml

    Requests 使用

        get 发送get请求,得到网页内容
        post 发送post请求,将数据提交给服务器,并返回结果
        params 传递请求参数

        response  get或post等得到的返回数据对象,相应对象,里包含下面几个结果
        -text,响应内容,文本
        -content,相应内容的二进制
        -json(),json格式数据
        -status_code,状态码
        raise_for_status()抛出异
        常,4xx,5xx
        -headers
        -cookies

        session 会话保持,使用已保存的cookies
        proxies 使用代理,进行请求转发
        timeout 连接超时指的是在你的客户端实现到远端机器端口的连接时
        (对应的是`connect()`_),Request 会等待的秒数。
    
    Beautifulsoup的使用:

        prettify() 漂亮的格式化打印内容
        text 返回标签里面的字符串
        tag html文档中的标签名
        find() 返回第一个找到的对象,只搜索子节点
        find_all() 返回所有找到的对象,只搜索子节点 
        get() 根据soup里面对象的属性取到数据,类似字典
        select() 使用css选择器选择页面中的class和id,标签属性等 

    重点学习find和find_all的参数们

        soup.find_all("title")
        # [<title>The Dormouse's story</title>]

        soup.find_all("p", "title")
        # [<p class="title"><b>The Dormouse's story</b></p>]

        soup.find_all("a")
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

        soup.find_all(id="link2")
        # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

        import re
        soup.find(text=re.compile("sisters"))
        # u'Once upon a time there were three little sisters; and their names were\n

    keyword 参数:

        如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.

        soup.find_all(id='link2')
        # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
        
        如果传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性:

        soup.find_all(href=re.compile("elsie"))
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

        搜索指定名字的属性时可以使用的参数值包括 字符串 , 正则表达式 , 列表, True .
        下面的例子在文档树中查找所有包含 id 属性的tag,无论 id 的值是什么:

        soup.find_all(id=True)
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

        使用多个指定名字的参数可以同时过滤tag的多个属性:

        soup.find_all(href=re.compile("elsie"), id='link1')
        # [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]

        有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:

        data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
        data_soup.find_all(data-foo="value")
        # SyntaxError: keyword can't be an expression
        
        但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:

        data_soup.find_all(attrs={"data-foo": "value"})
        # [<div data-foo="value">foo!</div>]

    按CSS搜索:

        按照CSS类名搜索tag的功能非常实用,但标识CSS类名的关键字 class 在Python中是保留字,使用 class 做参数会导致语法错误.从Beautiful Soup的4.1.1版本开始,可以通过 class_ 参数搜索有指定CSS类名的tag:

        soup.find_all("a", class_="sister")

        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

        class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True :

        soup.find_all(class_=re.compile("itl"))

        # [<p class="title"><b>The Dormouse's story</b></p>]

        def has_six_characters(css_class):
        return css_class is not None and len(css_class) == 6

        soup.find_all(class_=has_six_characters)

        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

        tag的 class 属性是 多值属性 .按照CSS类名搜索tag时,可以分别搜索tag中的每个CSS类名:

        css_soup = BeautifulSoup('<p class="body strikeout"></p>')
        css_soup.find_all("p", class_="strikeout")

        # [<p class="body strikeout"></p>]
        css_soup.find_all("p", class_="body")
        # [<p class="body strikeout"></p>]

        搜索 class 属性时也可以通过CSS值完全匹配:

        css_soup.find_all("p", class_="body strikeout")
        # [<p class="body strikeout"></p>]

        完全匹配 class 的值时,如果CSS类名的顺序与实际不符,将搜索不到结果:

        soup.find_all("a", attrs={"class": "sister"})
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
        
    text 参数:

        通过 text 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表, True . 看例子:

        soup.find_all(text="Elsie")
        # [u'Elsie']

        soup.find_all(text=["Tillie", "Elsie", "Lacie"])
        # [u'Elsie', u'Lacie', u'Tillie']

        soup.find_all(text=re.compile("Dormouse"))
        [u"The Dormouse's story", u"The Dormouse's story"]

        def is_the_only_string_within_a_tag(s):
            ""Return True if this string is the only child of its parent tag.""
            return (s == s.parent.string)

        soup.find_all(text=is_the_only_string_within_a_tag)

        # [u"The Dormouse's story", u"The Dormouse's story", u'Elsie', u'Lacie', u'Tillie', u'...']

        虽然 text 参数用于搜索字符串,还可以与其它参数混合使用来过滤tag.Beautiful Soup会找到 .string 方法与 text 参数值相符的tag.下面代码用来搜索内容里面包含“Elsie”的<a>标签:

        soup.find_all("a", text="Elsie")
        # [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]

    Tag 的调用:

        name 取到tag的名字
        attrs 取到字典形式的属性
        contents tag的子节点列表

    selenium的使用

        安装,下载对应浏览器的驱动
        pip install selenium

        常用操作:
        得到驱动对象driver
        driver = webdriver.Firefox()

        使用driver打开网页
        driver.get("http://www.google.com")

        定位
        <input type="text" name="passwd" id="passwd-id" />

        任何一种方式都可以
        element = driver.find_element_by_id("passwd
        element = driver.find_element_by_id("passwd-id")
        element = driver.find_element_by_name("passwd")
        element = driver.find_element_by_xpath("//input[@id='passwd-id']")

        对相应lxml
        /html/body/div[1]/header/div[2]/form/input
        多个元素:find_elements_by…
        element = driver.find_elements_by_css_selector('#passwd-id')
        . -> class
        # -> id
        来自 <http://selenium-python.readthedocs.io/navigating.html>

        发送命令
        elem.clear() # 情况默认值
        elem.send_keys("some text") # 输入任何字
        elem.send_keys(Keys.RETURN) # 键盘回车,更多:https://seleniumpython.readthedocs.io/api.html?highlight=quit#module-selenium.webdriver.common.keys

        # js命令,下拉滚动条
        driver.execute_script("window.scrollBy(0,4800)")
        driver.execute_script("window.scrollTo(0,
        document.body.scrollHeight);")

        隐式等待
        driver.implicitly_wait(10) # second

    具体案例可参照各种库和小练习里面的实例
    
"""


最后更新于:2018-06-15 13:43:38