精华内容
下载资源
问答
  • 3种网页抓取方法

    千次阅读 2019-04-28 20:39:06
    3种抓取其中数据的方法。首先是正则表达式,然后是流行的BeautifulSoup模块,最后是强大的lxml模块。 1 正则表达式 如果你对正则表达式还不熟悉,或是需要一些提示,那么你可以查阅...

    3种抓取其中数据的方法。首先是正则表达式,然后是流行的BeautifulSoup模块,最后是强大的lxml模块。

    1 正则表达式

    如果你对正则表达式还不熟悉,或是需要一些提示,那么你可以查阅https://docs.python.org/2/howto/regex.html获得完整介绍。即使你使用过其他编程语言的正则表达式,我依然推荐你一步一步温习一下Python中正则表达式的写法。

    由于每章中都可能构建或使用前面章节的内容,因此我建议你按照类似本书代码库的文件结构进行配置。所有代码都可以从代码库的code目录中运行,以便导入工作正常。如果你希望创建一个不同的结构,请注意需要变更所有来自其他章的导入操作(比如下述代码中的from chp1.advanced_link_crawler)。

    当我们使用正则表达式抓取国家(或地区)面积数据时,首先需要尝试匹配``元素中的内容,如下所示。

    >>> import re
    >>> from chp1.advanced_link_crawler import download
    >>> url = 'http://example.python-scraping.com/view/UnitedKingdom-239'
    >>> html = download(url)
    >>> re.findall(r'(.*?)', html)
    ['<img />
    ',
      '244,820 square kilometres',
      '62,348,447',
      'GB',
      'United Kingdom',
      'London',
      '<a>EU</a>
    ',
      '.uk',
      'GBP',
      'Pound',
      '44',
      '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
      '^(([A-Z]d{2}[A-Z]{2})|([A-Z]d{3}[A-Z]{2})|([A-Z]{2}d{2}    [A-Z]{
    2})|([A-Z]{2}d{3}[A-Z]{2})|([A-Z]d[A-Z]d[A-Z]{2})      |([A-Z]{2}d[A-Z]
    d[A-Z]{2})|(GIR0AA))$',
      'en-GB,cy-GB,gd',
      '<div><a>IE </a></div>
    
    ']
    

    从上述结果中可以看出,多个国家(或地区)属性都使用了``标签。如果我们只想抓取国家(或地区)面积,可以只选择第二个匹配的元素,如下所示。

    >>> re.findall('(.*?)', html)[1]
    '244,820 square kilometres'
    

    虽然现在可以使用这个方案,但是如果网页发生变化,该方案很可能就会失效。比如表格发生了变化,去除了第二个匹配元素中的面积数据。如果我们只在当下抓取数据,就可以忽略这种未来可能发生的变化。但是,如果我们希望在未来某一时刻能够再次抓取该数据,就需要给出更加健壮的解决方案,从而尽可能避免这种布局变化所带来的影响。想要该正则表达式更加明确,我们可以将其父元素``也加入进来,由于该元素具有ID属性,所以应该是唯一的。

    >>> re.findall('<label for="places_area">Area: </label>
    
    (.*?)', html)
    ['244,820 square kilometres']
    

    这个迭代版本看起来更好一些,但是网页更新还有很多其他方式,同样可以让该正则表达式无法满足。比如,将双引号变为单引号,``标签之间添加多余的空格,或是变更area_label等。下面是尝试支持这些可能性的改进版本。

    >>> re.findall('''.*?<tds>(.*?)''', html)
    ['244,820 square kilometres']
    

    虽然该正则表达式更容易适应未来变化,但又存在难以构造、可读性差的问题。此外,还有很多其他微小的布局变化也会使该正则表达式无法满足,比如在``标签里添加title属性,或者trtd元素修改了它们的CSS类或ID。

    从本例中可以看出,正则表达式为我们提供了抓取数据的快捷方式,但是该方法过于脆弱,容易在网页更新后出现问题。幸好,还有更好的数据抽取解决方案,比如我们将在本章介绍的其他抓取库。

    2 Beautiful Soup

    Beautiful Soup

    是一个非常流行的Python库,它可以解析网页,并提供了定位内容的便捷接口。如果你还没有安装该模块,可以使用下面的命令安装其最新版本。

    pip install beautifulsoup4

    使用Beautiful Soup的第一步是将已下载的HTML内容解析为soup文档。由于许多网页都不具备良好的HTML格式,因此Beautiful Soup需要对其标签开合状态进行修正。例如,在下面这个简单网页的列表中,存在属性值两侧引号缺失和标签未闭合的问题。

    <ul>
        <li>Area
        </li><li>Population
    </li></ul>
    
    
    
    
    

    如果Population列表项被解析为Area列表项的子元素,而不是并列的两个列表项的话,我们在抓取时就会得到错误的结果。下面让我们看一下Beautiful Soup是如何处理的。

    >>> from bs4 import BeautifulSoup
    >>> from pprint import pprint
    >>> broken_html = '<ul><li>Area</li><li>Population</li></ul>
    '
    >>> # parse the HTML
    >>> soup = BeautifulSoup(broken_html, 'html.parser')
    >>> fixed_html = soup.prettify()
    >>> pprint(fixed_html)
    
    <ul>
     <li>
      Area
      </li><li>
       Population
      </li>
     
    </ul>
    
    

    我们可以看到,使用默认的html.parser并没有得到正确解析的HTML。从前面的代码片段可以看出,由于它使用了嵌套的li元素,因此可能会导致定位困难。幸运的是,我们还有其他解析器可以选择。我们可以安装LXML(2.2.3节中将会详细介绍),或使用html5lib。要想安装html5lib,只需使用pip

    pip install html5lib

    现在,我们可以重复这段代码,只对解析器做如下变更。

    >>> soup = BeautifulSoup(broken_html, 'html5lib')
    >>> fixed_html = soup.prettify()
    >>> pprint(fixed_html)
       
         <ul>
           <li>
             Area
           </li>
           <li>
             Population
           </li>
         </ul>
    
    

    此时,使用了html5libBeautifulSoup已经能够正确解析缺失的属性引号以及闭合标签,并且还添加了标签,使其成为完整的HTML文档。当你使用lxml时,也可以看到类似的结果。

    现在,我们可以使用find()find_all()方法来定位我们需要的元素了。

    >>> ul = soup.find('ul', attrs={'class':'country_or_district'})
    >>> ul.find('li')  # returns just the first match
    <li>Area</li>
    >>> ul.find_all('li')  # returns all matches
    [<li>Area</li>
    
    , <li>Population</li>
    
    

    想要了解可用方法和参数的完整列表,请访问Beautiful Soup的官方文档。

    下面是使用该方法抽取示例网站中国家(或地区)面积数据的完整代码。

    >>> from bs4 import BeautifulSoup
    >>> url = 'http://example.python-scraping.com/places/view/United-Kingdom-239'
    >>> html = download(url)
    >>> soup = BeautifulSoup(html)
    >>> # locate the area row
    >>> tr = soup.find(attrs={'id':'places_area__row'})
    >>> td = tr.find(attrs={'class':'w2p_fw'}) # locate the data element
    >>> area = td.text # extract the text from the data element
    >>> print(area)
    244,820 square kilometres
    

    这段代码虽然比正则表达式的代码更加复杂,但又更容易构造和理解。而且,像多余的空格和标签属性这种布局上的小变化,我们也无须再担心了。我们还知道即使页面中包含了不完整的HTML,Beautiful Soup也能帮助我们整理该页面,从而让我们可以从非常不完整的网站代码中抽取数据。

    3 Lxml

    Lxml

    是基于libxml2这一XML解析库构建的Python库,它使用C语言编写,解析速度比Beautiful Soup更快,不过安装过程也更为复杂,尤其是在Windows中。最新的安装说明可以参考http://lxml.de/installation.html。如果你在自行安装该库时遇到困难,也可以使用Anaconda来实现。

    你可能对Anaconda不太熟悉,它是由Continuum Analytics公司员工创建的主要专注于开源数据科学包的包和环境管理器。你可以按照其安装说明下载及安装Anaconda。需要注意的是,使用Anaconda的快速安装会将你的PYTHON_PATH设置为Conda的Python安装位置。

    和Beautiful Soup一样,使用lxml模块的第一步也是将有可能不合法的HTML解析为统一格式。下面是使用该模块解析同一个不完整HTML的例子。

    >>> from lxml.html import fromstring, tostring
    >>> broken_html = '<ul><li>Area</li><li>Population</li></ul>
    
    '
    >>> tree = fromstring(broken_html) # parse the HTML
    >>> fixed_html = tostring(tree, pretty_print=True)
    >>> print(fixed_html)
    <ul>
        <li>Area</li>
        <li>Population</li>
    </ul>
    
    

    同样地,lxml也可以正确解析属性两侧缺失的引号,并闭合标签,不过该模块没有额外添加标签。这些都不是标准XML的要求,因此对于lxml来说,插入它们并不是必要的。

    解析完输入内容之后,进入选择元素的步骤,此时lxml有几种不同的方法,比如XPath选择器和类似Beautiful Soup的find()方法。不过,在本例中,我们将会使用CSS选择器,因为它更加简洁,并且能够在第5章解析动态内容时得以复用。一些读者可能由于他们在jQuery选择器方面的经验或是前端Web应用开发中的使用对它们已经有所熟悉。在本章的后续部分,我们将对比这些选择器与XPath的性能。要想使用CSS选择器,你可能需要先安装cssselect库,如下所示。

    pip install cssselect

    现在,我们可以使用lxml的CSS选择器,抽取示例页面中的面积数据了。

    >>> tree = fromstring(html)
    >>> td = tree.cssselect('tr#places_area__row > td.w2p_fw')[0]
    >>> area = td.text_content()
    >>> print(area)
    244,820 square kilometres

    通过对代码树使用cssselect方法,我们可以利用CSS语法来选择表格中ID为places_area__row的行元素,然后是类为w2p_fw的子表格数据标签。由于cssselect返回的是一个列表,我们需要获取其中的第一个结果,并调用text_content方法,以迭代所有子元素并返回每个元素的相关文本。在本例中,尽管我们只有一个元素,但是该功能对于更加复杂的抽取示例来说非常有用。

    本文摘自:《用Python写网络爬虫(第2版)》
    作者:[德]凯瑟琳 雅姆尔(Katharine Jarmul)、[澳]理查德 劳森(Richard Lawson)
    译者:李斌

    针对Python 3.6版本编写。


    提供示例完整源码和实例网站搭建源码,确保用户能在本地成功复现爬取网站环境,并保障网站的稳定性与可靠性以及代码运行结果的可再现性。


    Internet上包含了许多有用的数据,其中大部分是可以免费公开访问的。但是,这些数据不容易使用,它们内嵌在网站的架构和样式中,在提取时也需要多加小心。网络爬取技术作为一种收集和理解网络上海量信息的方式,正变得越来越有用。


    本书是使用Python 3.6的新特性来爬取网络数据的入门指南。本书讲解了从静态网站提取数据的方法,以及如何使用数据库和文件缓存技术来节省时间并管理服务器负载,然后介绍了如何使用浏览器、爬虫和并发爬虫开发一个更为复杂的爬虫。


    借助于PyQt和Selenium,你可以决定何时以及如何从依赖JavaScript的网站上爬取数据,以及更好地理解在受CAPTCHA保护的复杂网站上提交表单的方法。本书还讲解了使用Python包(比如mechanize)进行自动化处理的方法、使用Scrapy库创建基于类的爬虫的方法,以及如何在真实的网站上实施所学的爬虫技巧。


    本书最后还涵盖了使用爬虫对网站进行测试、远程爬取技术、图像处理以及其他相关的主题。


    展开全文
  • 接口抓取工具

    2018-07-02 14:14:50
    接口抓取工具,可以抓取所有网页接口,有利于更好的开发和学习
  • 说到网页内容的抓取,最常用的两种方式: 1.利用file_get_contents()函数,简简单单; 2.CURL抓取工具。CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们...

    说到网页内容的抓取,最常用的两种方式:

    1.利用file_get_contents()函数,简简单单;

    2.CURL抓取工具。CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。curl尤其是在api接口调用过程中用处广泛。

    下面现说file_get_contents()函数,不多说,实例说话。


    <?php
    $url = 'http://www.smartbc.cn/jfdz/download.php?P_ID=57';
    $s = file_get_contents($url);
    echo bin2hex(substr($s, 0, 20));//
    //bin2hex函数把包含数据的二进制字符串转换为十六进制值

    上面程序的意思就是抓取某一网址下的下载文件的二进制内容。

    之后,开始说下curl的使用,步骤如下:
    1.初始化连接句柄;2.设置CURL选项;3.执行并获取结果;4.释放VURL连接句柄。

    1. curl_init() 和 curl_close() 分别是初始化CURL连接和关闭CURL连接,都比较简单。
    2. curl_exec() 执行CURL请求
    3. CURL函数库里最重要的函数是curl_setopt(),它可以通过设定CURL函数库定义的选项来定制HTTP请求。
    4. 上述代码片段中使用了三个重要的选项:
    5. CURLOPT_URL 指定请求的URL;
    6. CURLOPT_RETURNTRANSFER 设置为1表示稍后执行的curl_exec函数的返回是URL的返回字符串,而不是把返回字符串定向到标准输出并返回TRUE;
    7. CURLLOPT_HEADER设置为0表示不返回HTTP头部信息。

    
    

    function http_curl($url,$type ='get', $res = 'json',$arr= '')
    	{//curl 获取工具
    		// 1.初始化curl
    		$ch = curl_init();
    		// 2.设置curl的参数
    
    		curl_setopt($ch, CURLOPT_URL, $url);
    		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
    		//curl_setopt($ch,CURLOPT_HEADER,0);
    		if ($type =='post') {
    			//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    			//curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
    			//curl_setopt($ch,CURLOPT_URL,1);
    			curl_setopt($ch,CURLOPT_POST,1);
    			curl_setopt($ch,CURLOPT_POSTFIELDS,$arr);
    		}
    		// 3.采集
    		$output = curl_exec($ch);
    		
    		// 4.关闭
    		curl_close($ch);
    		if($res == 'json'){
    			// var_dump($output);
    			//echo curl_errno($ch);
    			if (curl_errno($ch)) {
    				//请求失败,返回错误信息
    				return curl_error($ch);
    			} else {
    				// 请求成功,返回json数组
    				//echo "json";
    				return json_decode($output,true);
    			}
    		}
    	}//上面这段代码是小编再进行微信公众平台开发时候,写的一个抓取函数,大家可以根据自己的需求进行修改。
    
    
    展开全文
  • 动态网页抓取

    千次阅读 热门讨论 2021-06-04 21:32:21
    文章目录已写章节第五章 动态网页抓取(Selenium)5.1 Ajax的原理5.2 Selenium的使用5.2.1 准备工作5.2.2 Selenium的使用1. 声明浏览器对象2. 访问页面3. 查找节点4. 查找多个节点5. 节点交互6. 动作链7. 滑动页面8....

    已写章节

    第一章 网络爬虫入门
    第二章 基本库的使用
    第三章 解析库的使用
    第四章 数据存储
    第五章 动态网页的抓取


    第五章 动态网页的抓取(Selenium)

    有时候我们在用requests抓取页面的时候,得到的结果可能和我们在浏览器中看到的结果不一样:在浏览器中可以正常看到页面数据,但是使用requests得到的结果并没有。这是因为requests库获取的都是原始的HTML文档,而在浏览器中看到的页面是经过JavaScript处理数据后生成的结果,这些数据来源有很多种,可能是通过Ajax加载的,可能是包含在HTML文档中的,也有可能是经过JavaScript和特定的算法计算后生成的。如果是通过Ajax加载的,原始页面最初不会包含某些数据,原始页面加载完之后,会再向服务器请求某个接口获取数据,然后数据才被处理从而呈现在网页上,这其实就是发生了一个Ajax请求。如果遇到这样的页面,需要分析出网页后台向服务器发送的Ajax请求,如果可以使用requests来模拟Ajax请求,那么就可以成功抓取了。


    5.1 Ajax的原理

    Ajax(Asynchronous JavaScript nad XML),即异步的JavaScript和XML。它不是一门编程语言,而是利用JavaScript在保证网页不被刷新、页面不改变的情况下与服务器交换数据并更新部分网页的技术。

    例如:打开tx视频,在电影中,鼠标的滑轮向下划,你会发现电影好像没有尽头,有时候最下面会出现加载的动画。页面其实并没有整个刷新,链接也并没有变化,但是网页中新增加了电影,这就是通过Ajax获取新数据并呈现的过程。

    Ajax有其特殊的请求类型,它是xhr,可以在Chrome的检查中选择xhr查看。

    模拟Ajax请求来爬取tx视频的例子:

    import requests
    from fake_useragent import UserAgent
    from lxml import etree
    import re
    from typing import NoReturn, List
    import time
    import mysql.connector
    
    def start() -> NoReturn:
        first_url = 'https://v.qq.com/channel/movie?listpage=1&channel=movie&itype=100062'
        base_url = 'https://v.qq.com/x/bu/pagesheet/list?append=1&channel=movie&itype=100062&listpage=2&offset={}&pagesize=30'
        create_table()
        storage_MysqlDB(get_page(first_url), 1)
        page_numbers = ((get_number_of_movies(first_url)-30)//30)+1
        for i in range(1, page_numbers):
            url = base_url.format(str(i*30))
            storage_MysqlDB(get_page(url), (i*30)+1)
            # time.sleep(5)
    
    
    def get_number_of_movies(url: str) -> int:
        headers = {
            'user-Agent': UserAgent().chrome
        }
        response = requests.get(url=url, headers=headers)
        response.encoding = response.apparent_encoding
        e = etree.HTML(response.text, etree.HTMLParser())
        number_of_movies = e.xpath('//body/div[5]/div/div/div/span/text()')[0]
        return int(number_of_movies)
    
    def get_page(url: str) -> List[List]:
        response = requests.get(url=url, headers={'user-Agent': UserAgent().chrome})
        response.encoding = response.apparent_encoding
        e = etree.HTML(response.text, etree.HTMLParser())
    
        all_div = e.xpath('//div[@class="list_item"]')
        res = []
        for div in all_div:
    
            movies_name = div.xpath('./div[1]/a/@title')
    
            hrefs = div.xpath('./div[1]/a/@href')
    
            performers = div.xpath('./div[1]/div/text()')
            performers = [i.replace('主演:', '') for i in performers]
    
            number_of_observers = div.xpath('./div[2]/text()')
    
            film_length = div.xpath('./a/div[1]/text()')
    
            score = div.xpath('./a/div[2]/text()')
    
    
    
            if len(movies_name) == 0:
                movies_name = ['None']
    
            if len(hrefs) == 0:
                hrefs = ['None']
    
            if len(performers) == 0:
                performers = ['None']
    
            if len(number_of_observers) == 0:
                number_of_observers = ['None']
    
            if len(film_length) == 0:
                film_length = ['None']
    
            if len(score) == 0:
                score = ['None']
    
            tem = []
            tem.append(str(movies_name[0]))
            tem.append(str(hrefs[0]))
            tem.append(str(performers[0]))
            tem.append(str(number_of_observers[0]))
            tem.append(str(film_length[0]))
            tem.append(str(score[0]))
            res.append(tem)
        print(res)
        return res
    
    
    def create_table():
        mydb = mysql.connector.connect(
            host='localhost',
            user='root',
            passwd='123456',
            port=3307,
            charset='utf8'
        )
        mycursor = mydb.cursor()
        sql_create_table = [
            "USE reptile;",
            "CREATE TABLE IF NOT EXISTS tencent_movies(\
             ID INT AUTO_INCREMENT COMMENT '编号',\
             movies_name VARCHAR(40) COMMENT '电影名',\
             hrefs VARCHAR(100) COMMENT '链接',\
             performers VARCHAR(100) COMMENT '主演',\
             number_of_observers VARCHAR(20) COMMENT '播放量',\
             film_length VARCHAR(20) COMMENT '电影时长',\
             score varchar(4) COMMENT '评分',\
             PRIMARY KEY(ID)\
             )COMMENT = 'All movie information in Tencent video'\
             ENGINE = INNODB CHARSET='utf8mb4' COLLATE='utf8mb4_unicode_ci';"
        ]
        for i in sql_create_table:
            mycursor.execute(i)
    
    def storage_MysqlDB(data: List, start: int)-> None:
        mydb = mysql.connector.connect(
            host='localhost',
            user='root',
            passwd='123456',
            port=3307,
            charset='utf8',
            database='reptile'
        )
        mycursor = mydb.cursor()
        sql_insert = "insert into tencent_movies values(%s, %s, %s, %s, %s, %s, %s)"
        for i in data:
            i.insert(0, start)
            new_i = tuple(i)
            mycursor.execute(sql_insert, new_i)
            # print(start)
            # time.sleep(1)
            start += 1
        mydb.commit()
        mycursor.close()
    
    if __name__ == '__main__':
        start()
    

    在上面,我们介绍了Ajax,并使用requests来模拟Ajax请求来爬取数据。

    但是,JavaScript动态渲染页面不止Ajax这一种。有很多网页是由JavaScript产生的,并不会包含Ajax请求。淘宝页面也是使用Ajax来获取数据的,但是,他的Ajax接口中包含许多的加密参数,我们很难找出其规律,也很难使用requests来模拟Ajax请求。

    为了解决这些问题,我们可以直接使用模拟浏览器的方式来实现,这样就可以做到在浏览器中看到什么样子,抓取的源码就是什么样子。


    5.2 Selenium的使用

    Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如下拉、点击按钮、在文本框中输入文字、下划页面等动作,同时还可以获取浏览器当前呈现的页面的源代码。可以将Selenium看做是个通过代码来控制浏览器的工具。


    5.2.1 准备工作

    • 需要下载与你的Chrome版本相对应的ChromeDriver
    • 安装Selenium库
    • 将下载好的浏览器驱动放在Python的安装目录下的Scripy目录中

    注意:使用Edge的驱动器会提示要将驱动添加到path中,可以在初始化一个Edge浏览器对象的时候传入Edge驱动的路径:

    from selenium import webdriver
    
    browser = webdriver.Edge('E:\python\Scripts\msedgedriver.exe') 
    browser.get('https://www.baidu.com')
    

    所以建议大家使用Chrome浏览器。

    ChromeDriver下载地址

    Edge驱动下载地址

    Selenium官方文档


    5.2.2 Selenium的使用

    当所有的准备工作都完成后,打开编辑器,来敲代码了。

    首先来看看下面这个小例子:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    browser = webdriver.Chrome()  # 声明一个chrome浏览器对象
    try:
        browser.get('https://www.baidu.com')   # 打开指定的网页
        input = browser.find_element_by_id('kw')   # 寻找搜索框
        input.send_keys('Python')   # 在搜索框中输入指定的内容
        input.send_keys(Keys.ENTER)
        wait = WebDriverWait(browser, 10)
        wait.until(EC.presence_of_all_elements_located((By.ID, 'content_left')))
        print(browser.current_url)  # 打印当前页面的url
        print(browser.get_cookies()) # 打印当前页面的cookies
        print(browser.page_source)  # 打印当前页面的源代码
    finally:
        browser.close()
    

    执行上面的代码,如果一切正常的话,你的电脑应该自动打开了Chrome浏览器并来到了百度的首页,然后自动在搜索框中输入了“Python”并点击了搜索按钮,控制台中打印出当前页面的url、cookie、页面源代码。


    1. 声明浏览器对象

    Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。

    下面是初始浏览器的方法:

    from selenium import webdriver
    
    browser = webdriver.Chrome()
    browser = webdriver.Firefox()
    browser = webdriver.Edge()
    browser = webdriver.PhantomJS()
    browser = webdriver.Safari()
    

    注意:
    可以指定驱动器路径来初始化浏览器对象:

    browser = webdriver.Edge(‘E:\python\Scripts\msedgedriver.exe’)


    2. 访问页面

    可以使用get()方法来请求网页,将要请求的url传入即可,下面是请求百度的例子:

    from selenium import webdriver
    import time
    
    browser = webdriver.Edge('E:\python\Scripts\msedgedriver.exe')
    browser.get('https://www.baidu.com')
    print(browser.page_source)
    time.sleep(10)
    browser.close()
    

    3. 查找节点

    Selenium可以驱动浏览器完成各种操作,比如填充表单、模拟点击等。比如,我们想要完成在某个输入框输入文本的操作,我们首先需要使用selenium查找到这个输入框所在的节点位置。


    • 查找单个节点的常用方法

      查找单个节点的方法
      find_element_by_id() 通过节点的id属性值来查找单个节点
      find_element_by_name() 通过节点的name属性值来查找单个节点
      find_element_by_xpath() 通过xpath来查找单个节点
      find_element_by_link_text() 通过完整的链接文本(点击该文本就会跳到另一个页面)查找单个节点
      find_element_by_partial_link_text() 通过部分链接文本来查找单个节点
      find_element_by_tag_name() 通过节点的标签名来查找单个节点
      find_element_by_class_name() 通过节点的class属性值来查找单个节点
      find_element_by_css_selector() 通过css来查找当个节点
      find_element(By.ID,‘ ’) 同find_element_by_id()
      find_element(By.CLASS_NAME, ‘ ’) 同find_element_by_class_name()
      find_element(By.CSS_SELECTOR,’ ’) 同find_element_by_css_selector()
      find_element(By.LINK_TEXT,’ ’) 同find_element_by_link_text()
      find_element(By.NAME,’ ’) 同find_element_by_name()
      find_element(By.PARTIAL_LINK_TEXT,’ ’) 同find_element_by_partial_link_text()
      find_element(By.TAG_NAME,’ ’) 同find_element_by_tag_name()
      find_element(By.XPATH,’ ’) 同find_element_by_xpath()

    例子:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    browser = webdriver.Chrome()
    url = 'https://www.taobao.com/'
    browser.get(url)
    print(browser.find_element(By.ID, 'q'))
    print(browser.find_element_by_id('q'))
    print(browser.find_element_by_xpath('//*[id="q"]'))
    print(broswer.find_element_by_css_selector('#q'))
    

    运行结果:

    <selenium.webdriver.remote.webelement.WebElement (session="5e8df8d577c9340c9524ecebcf924800", element="18f8aa32-46d6-43cd-89b1-67e48e314310")>
    <selenium.webdriver.remote.webelement.WebElement (session="5e8df8d577c9340c9524ecebcf924800", element="18f8aa32-46d6-43cd-89b1-67e48e314310")>
    <selenium.webdriver.remote.webelement.WebElement (session="5e8df8d577c9340c9524ecebcf924800", element="18f8aa32-46d6-43cd-89b1-67e48e314310")>
    <selenium.webdriver.remote.webelement.WebElement (session="5e8df8d577c9340c9524ecebcf924800", element="18f8aa32-46d6-43cd-89b1-67e48e314310")>
    

    4. 查找多个节点

    在网页中如果查找的节点有多个,使用find_element()方法将只会找到第一个节点,如果想要查找多个节点,就需要使用find_elements()方法。

    from selenium import webdriver
    
    with webdriver.Chrome() as browser:
        browser.get('https://www.taobao.com')
        all_nodes = browser.find_elements_by_xpath('//li[@class="J_Cat a-all"]')
        print(len(all_nodes))
        print(all_nodes)
    

    上面的代码将自动使用Chrome打开淘宝的主页,打印出查找到的淘宝主页左上角的15个导航栏。

    将上面的表格中查找单个节点的方法中的element改为elements就是查找多个节点的方法。


    5. 节点交互

    Selenium可以驱动浏览器来执行一些操作,也就是可以让浏览器执行一些动作。

    常用的有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击时用click()方法。

    from selenium import webdriver
    import time
    
    with webdriver.Chrome() as browser:
        browser.get('https://www.taobao.com')  # 打开链接
        input = browser.find_element_by_xpath('//*[@id="q"]')  # 找到搜索框
        input.send_keys('背包')  # 在搜索框中输入背包
        time.sleep(5)
        input.clear()  # 清空搜索框
        input.send_keys('书包')  # 在搜索框中输入书包
        search_button = browser.find_element_by_xpath('//button[@class="btn-search tb-bg"]')  # 查找搜索按钮
        time.sleep(5)
        search_button.click()  # 点击搜索按钮
    

    6. 动作链

    上面的选择输入框、向输入框中输入文本、点击按钮等动作,都是有特定的执行对象;但是,对于鼠标移动、按盘按键等,这些动作由另一种方式来执行,这就是动作链。

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    import time
    
    browser = webdriver.Chrome()
    browser.get('示例网站的url')
    browser.find_element_by_xpath('//input[@placeholder="请输入邮箱"]').send_keys('jxd')
    time.sleep(1)
    browser.find_element_by_xpath('//input[@placeholder="请输入密码"]').send_keys('123456')
    time.sleep(1)
    browser.find_element_by_xpath('//div[@class="geetest_wait"]').click()
    time.sleep(1)
    
    # 更换监视界面
    ifame = browser.find_element_by_xpath('//div[@class="inner-conntent"]')
    browser.switch_to.frame(ifame)
    # 要拖动的元素
    source = browser.find_element_by_xpath('//div[@class="geetest_slider_button"]')
    # 要拖动到的位置元素
    target = browser.find_element_by_xpath('//div[@class="geetest_slider_tip geetest_fade"]')
    actions = ActionChains(browser)
    actions.drag_and_drop(source, target)
    actions.perform()
    

    7. 滑动页面

    滑动页面其实就是执行js语句,可以将控制页面滑动的js语句放在driver.execute_script(js语句)中来执行:

    driver.execute_script('window.scrollBy(0,1000)')  # 滑动的距离,分为x轴和y轴
    
    driver.execute_script('window.scrollTo(0,1000)')  # 滑动到指定的坐标
    
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")  # 滑动到页面的最下方
    
    driver.execute_script("document.getElementById('page').scrollIntoView(true)") # 将查找到的元素显示在屏幕中间,scrollIntoView(false)就是将查找到的元素显示在屏幕的底部 
    

    8. 执行JavaScript

    上面的向下滑动页面就是执行JavaScript的例子,我们可以使用driver.execute_script(javascript语句)来执行JavaScript代码。


    9. 获取节点的信息

    方法 作用
    WebElement.get_attribute(‘属性名’) 获取标签指定的属性的属性值
    WebElement.text 获取标签的文本
    WebElement.id 获取标签的id
    WebElement.location 获取标签在页面中的相对位置
    WebElement.tag_name 获取标签的标签名
    WebElement.size 获取标签的大小

    10. 切换Frame

    网页中有一种节点叫做iframe,也就是子页面,我们使用selenium提供的选择节点的方法是在父级Frame里面操作,而如果页面中有子页面,它是不能获取到子Frame中的节点的。此时,就需要使用switch_to.frame()方法来切换Frame,上面的例子中有。

    注意:switch_to.frame()默认接收的是目标frame节点的id或name,如果目标节点没有id属性和name属性,那么就可以传入一个用select_element_by_xpath()等方法定位到的WebElement对象。


    11. 等待

    有时我们请求的页面中的元素或节点是通过Ajax加载的,就需要一定的时间,在元素未加载出来之前我们去查找该元素就会找不到,所以,就需要等待一段时间,等元素加载出来之后再执行查找元素等一系列操作。


    隐式等待:在查找节点而节点并没有立即出现时,隐式等待会等待一段时间再查找节点,时间默认是0秒,如果还未找到节点就会抛出节点未找到的异常。隐式等待可以看做是time.sleep()方法。

    browser.imlicitly_wait(10)  # 隐式等待10秒钟
    

    显示等待:规定一个最长等待时间,在这段时间里如果查找到了节点就返回节点,如果在这段时间里还找到该节点,则抛出超时异常。

    from selenium.webdriver.support import expected_conditions as EC
    
    wait = WebDriverWait(browser, 10)  # 设置显式等待时间是10秒
    input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
    

    until()方法接收一个等待条件expected_conditions,上面的例子中的等待条件是presence_of_element_located(),指的是节点出现的意思,其参数是节点的定位元组,也就是ID为q的节点。


    常见的等待条件

    等待条件 含义
    title_is 标题是某内容
    title_contains 标题包含某内容
    presence_of_element_located 节点加载出来,传入定位元组,如(By.ID, ‘p’)
    visibility_of_element_located 节点可见,传入定位元组
    visibility_of 节点可见,传入节点对象
    presence_of_all_elements_located 所有节点加载出来
    text_to_be_present_in_element 某个节点文本包含某个文字
    text_to_be_present_in_element 某个节点值包含某个文字
    frame_to_be_avaliable_and_switch_to_it 加载并切换
    invisibility_of_element_located 节点不可见
    element_to_be_clickable 节点可点击
    staleness_of 判断 个节点是否仍在 DOM ,可判断页面是杏已经刷新
    element_ to_be_selected 节点可选择,传节点对象
    element_located_to_be_selected 节点可选择,传人定位元组
    element_selection_state_to_be 传人节点对象以及状态,相等返回 True ,否则返回 False
    element_located_selection_state_to_be 传入定位元组以及状态,相等返回 True ,否则返回 False
    alert_is_present 是否出现警告

    12. 控制页面前进和后退

    from seleniun import webdriver
    
    browser.forward()    # 前进
    browser.back()   # 后退
    

    13. 对cookies的操作

    from selenium import webdirver
    
    browser.get_cookies()  # 返回字典类型的所有cookies
    browser.add_cookies()  # 添加一个cookies,参数是字典类型
    browser.delete_all_cookies()   # 删除所有的cookies
    

    14. 选项卡

    from selenium import webdriver
    import time
    
    browser = webdriver.Chrome()  # 初始化一个浏览器对象
    
    browser.get('https://www.baidu.com')  # 访问百度
    browser.execute_script('window.open()')   # 新开启一个选项卡
    time.sleep(2)
    
    print(browser.window_handles)  # 打印所有选项卡代号列表
    
    browser.switch_to.window(browser.window_handles[1])   # 更换到选项卡代号列表中的第一个选项卡
    time.sleep(1)
    
    browser.get('https://www.taobao.com')
    browser.switch_to.window(browser.window_handles[0])
    time.sleep(1)
    
    browser.get('https://python.org')
    

    15. 模拟输入键盘

    上面讲的sendkeys()方法可以向输入框中输入文字,它还可以实现模拟键盘的输入,甚至是组合键。

    from selenium.webdriver.common.keys import Keys
    
    driver = webdriver.Firefox()
    driver.get([https://www.baidu.com](https://www.baidu.com/))
    
    el = driver.find_element(By.ID, "kw") # 找到输入框
    el.send_keys(“seleniumm”)             # 在输入框中输入"seleniumm"
    el.send_keys(Keys.BACK_SPACE)         # 模拟按一下Backspaece键
    el.send_keys(Keys.SPACE)              # 模拟按一下Space键
    el.send_keys(“教程”)                  # 输入"教程"
    el.send_keys(Keys.CONTROL, ‘a’)       # 模拟按下 "a"键
    el.send_keys(Keys.CONTROL, ‘x’)       # 模拟按下 "x"键
    el.send_keys(Keys.CONTROL, ‘v’)       # 模拟按下 "v"键
    el.send_keys(Keys.ENTER)              # 模拟按下"enter"键
    

    16. 异常处理

    selenium的异常类型都在selenium.common.exceptions这个包中,下面列举了常用的异常:

    异常 说明
    NoSuchElementException 未找到节点
    NoSuchAttributeException 节点没有改属性
    NoSuchFrameException frame未找到
    NoSuchWindowException window未找到

    知道这些常用的异常之后,就可以使用try except来将这些异常捕获并做相应的处理了。


    5.3 使用Selenium的例子

    使用Selenium爬取手机信息


    感谢你的阅读!

    展开全文
  • //有时候,你要获取一个网页中表格中的所有内容,可能该表格内容过多会分页显示,这时候,表格的内容不显示完全,你是不可以获取到全部内容的,然后你可以试试以下代码: //获取js选择器 ...
    Selenium也是一个用于Web应用程序测试的工具。Selenium测试直接在浏览器中运行,就像真实用户所做的一样。Selenium 测试可以在 Windows、Linux 和 Macintosh上的Internet Explorer、Mozilla 和 Firefox 中运行
    在这里以chrome 为例 进行介绍
    1)安装 chrome 浏览器
     2)下载 chromedriver地址:https://code.google.com/p/chromedriver/
      3)下载 selenium-java http://docs.seleniumhq.org/download/


    //有时候,你要获取一个网页中表格中的所有内容,可能该表格内容过多会分页显示,这时候,表格的内容不显示完全,你是不可以获取到全部内容的,然后你可以试试以下代码:
    //获取js选择器
    JavascriptExecutor js = (JavascriptExecutor) driver;
    //因为你要点击类似“更多”这样的按钮,才能显示后部分内容,arguments[0].click()就是点击,后面的参数意思是通过id找到这个按钮,当然,你也可以通过其他方式找到需要点击的按钮。
    js.executeScript("arguments[0].click();", driver.findElement(By.id("more_count")));
    另外,还可以参考下面的例子



    展开全文
  • Fiddler如何抓取接口

    万次阅读 2016-09-30 16:23:41
    前几天在学习接口的时候,苦于对于项目没有实质的接口,因为自己没有拿到接口的测试方法,于是,也不好意思向开放提要求,要求提供接口文档。虽然说,对于后台来说,接口文档是必须的,但是各个公司有各个公司的规则...
  • 这个时候就可以查看网页使用什么样的请求获取到的数据,那我们采用一样的请求方式就可以获取到数据了。 点击F12打开编程模式,如果下面有内容就点一下clear清空一下 然后点击翻页,右边就会显示发起的请求,
  • 网页抓取神器hawk使用心得

    千次阅读 2016-08-07 12:30:24
    (1)抓取目的现在网站有大量数据,但网站本身并不提供api接口,如果要批量获得这些页面数据,必须通过网页抓取方式实现。 比如某房产网站的二手房数据,在页面上很整齐的展示,因此可以通过分析网页的html源码,...
  • 网页截图及TDK抓取

    2020-07-08 09:54:51
    接口名称:网页截图及TDK抓取 接口平台:挖数据 在线使用:https://www.storeapi.net/url_capture.html 接口地址: https://api.storeapi.net/api/98/229(支持:http/https) 返回格式:json,xml 请求方式:POST 请求...
  • Python爬虫4.2 — ajax(动态网页数据抓取)用法教程

    千次阅读 多人点赞 2019-10-18 10:18:37
    Python爬虫4.2 — ajax[动态网页数据]用法教程综述AJAX 介绍什么是AJAX实例说明请求分析获取方式实例说明其他博文链接 综述 本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万...
  • 网页资源抓取

    千次阅读 2005-10-20 11:14:00
    对于MSIE,可以使用微软提供的IHTMLDocument2的接口,获取源代码,解析源代码中的url地址,显示在列表中,根据用户的选择,将地址到导给flashget来下载基本的步骤如下:1。获得IE的窗口,我使用了类似spy++的抓窗口...
  • Linux 抓取网页实例(shell+awk)

    万次阅读 多人点赞 2012-06-05 17:19:33
    上一篇博客讲了Linux抓取网页的方式,有curl和wget两种方式,这篇将重点讲Linux抓取网页的实例——抓取google play全球12国的游戏TOP排名要抓取google play游戏排名网页,首先需要分析网页的特点和规律:1、google ...
  • C#实现web信息自动抓取

    千次阅读 2008-06-14 16:04:00
    NetBug--爬虫 V1.02开发笔记 背景 随着Internet...这就需要Internet信息抓取程序来代替人工的操作。 所谓Internet信息抓取程序,就是程序会按照用户的关键词或关键网站来收集相应的信息,并提供给用户想要的信息格式。
  • delphi网页数据抓取

    千次阅读 2011-10-14 17:33:03
    简单: IdHttp:TIdHttp; Params:TStrings; Begin Params:=TStrinList.Create; IdHttp:=TIdHttp.Create(Nil); //提交网页的参数 Params.Add('参数1=XXX');
  • selenium抓取动态网页数据

    千次阅读 2019-04-04 15:17:00
    1.selenium抓取动态网页数据基础介绍 1.1 什么是AJAX  AJAX(Asynchronouse JavaScript And XML:异步JavaScript和XML)通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新,这意味着可以在不重新...
  • Android开发_Jsoup抓取网页信息

    千次阅读 2013-07-17 12:50:39
    想要抓取别的网页的信息,比较好的方法就是jsoup抓取,保存html为 documents 解析有用信息就可以! http://www.open-open.com/jsoup/ 一般情况下jsoup多用于JAVA方面的开发,可以利用jQuery,DOM一同使用。...
  • PowerShell 抓取网页表格

    千次阅读 2016-05-30 20:35:33
    今天无意中看到了传教士写的一篇博文http://www.cnblogs.com/piapia/p/5367556.html(PowerShell中的两只爬虫),很受启发,自己试着抓了一下,成功地抓取网页的表格。因为我是英文版的系统,中文系统的界面转换成...
  • selenium自动翻页抓取保监会数据

    千次阅读 2018-11-02 12:22:25
    抓取保监会官网产品检索页面下的所属公司,产品名称,备案日期,险种时,页面较多需要翻页抓取,经分析,在点击下一页,网页的url没有任何变化,只是用js去加载了新的数据,然后动态地改变了table里面的数据。...
  • 关于Fiddler工具,早在之前的《Python接口自动化测试框架实战开发(一)》、《自动化接口实战(一)》、《电商项目测试实战(四)》系列博客中有详细介绍使用 文章目录一、Fiddler 基础1.什么是 Fiddler2.Fiddler 的...
  • python自动化(五)接口自动化:1.接口测试基础

    千次阅读 多人点赞 2021-05-16 19:32:17
    接口测试价值与体系 二.常见的接口协议 1.TCP/IP协议 TCP/IP协议是在OS7层模型上总结生成的。 TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的...
  • 为了知道POST方法所需要传递的HTTP请求头部和请求体,我们可以使用Fiddler来进行抓包,抓取上网过程中HTTP请求中的POST方法。为了验证Fiddler抓取到的POST请求,可以使用Postman进行测试验证。在Postman中完成测试后...
  • c#抓取网页分析

    千次阅读 2006-11-23 15:41:00
    c#抓取网页分析目的:抓取网页,分析网页内容,进行处理获取信息。例子:抓km169上的adsl用户的费用信息,分析存储到本地数据库。步骤:1、抓取。2、分析。3、存储。
  • 第四章 接口自动化测试用例详解

    千次阅读 2015-04-09 17:28:26
    现在我们开始讲解接口自动化测试用例的编写。在本章编写的测试用例中,我们只针对具体的接口,编写自动化测试用例,而不对代码架构进行规划,那些儿进阶性的知识点,我们将在后面的章节讲解。先学习如何砌砖,然后...
  • Python3网络爬虫(一):利用urllib进行简单的网页抓取

    万次阅读 多人点赞 2017-02-28 23:32:35
    四、自动获取网页编码方式的方法  获取网页编码的方式有很多,个人更喜欢用第三方库的方式。  首先我们需要安装第三方库chardet,它是用来判断编码的模块,安装方法如下图所示,只需要输入指令: pip ...
  • 前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何...为了解放双手,就用 Python 代码撸一个,选择 MitmProxy 代理作为抓包工具,因为它可以使用 Python 代码监听抓取到的 url,用于自动获取 cookie 等
  • 判断根目录是否存在favicon的方法可以采用返回码是200且contentLength>0的方法 return HttpURLConnection.HTTP_OK == connection.getResponseCode() && connection.getContentLength() > 0; 那么到此为止从网站...
  • 网页抓取城市间的距离

    千次阅读 热门讨论 2016-08-19 17:04:53
    一个项目需要全国重点城市间的距离,网上有这种查询,可是手工查询的速度是无法忍受的,所以需要通过程序自动抓取。这儿说一下其中的关键点。 查询的网址是http://tools.2345.com/jiaotong/lc.htm,这儿截取该网页...
  • Appium + mitmproxy 全自动抓取APP 数据

    千次阅读 2020-07-14 17:26:54
    发现只有少数 APP 网络请求参数未做签名处理,像这类的能直接分析 url 和 param,利用 python 全自动化获取数据,但是大部分比如网易新闻这类 APP 安全级别较高,参数做了加密或者签名校验,服务端也有同一签名的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,214
精华内容 6,485
关键字:

网页接口自动抓取方法