zoukankan      html  css  js  c++  java
  • 学习Python(三)

    学习Python(一)

     https://blog.csdn.net/u010608296/article/details/104561555

    7 xpath

    首先安装GoogleChrome浏览器

    7.1 chrome浏览器中安装xpath插件

    Chrome浏览器中,访问 chrome://extensions/ ,打开开发者模式

     

    把xpath_helper_2_0_2.crx拖动到Chrome中即可

     

    点击“添加扩展程序”即可添加Chrome插件。

    对于新版本的Chrome67以上的)会报告错误

    crx后缀名改为rar,并解压到当前目录。

     

    然后,点击“加载已解压的扩展程序”把解压后的rar文件目录加载。

    安装后的效果

     

    并且右上角出现了x’。访问任意页面,比如www.baidu.com,点击’x’,即可打开xpath功能。

     

    7.2 xpath语法

    以贴吧为例:https://tieba.baidu.com/f?kw=%E6%9F%AF%E5%8D%97&pn=50 

    1 查找标签

    1.1 父目录查找。(以//开头)

    //div

    //a

    //span

    1.2 当前路径下查找(以./开头)

    ./div

    ./a

    ./span

    1.3 子路径查找(在父目录下查找子目录)

    //div/span

    //div/a

    //li/div/div/div/div/a

    //li//a

    //li/div//a

    2 查找属性。

    2.1 属性全匹配

    格式如下:

    标签名[@属性名=属性值]

    比如:

    //a[@class="j_th_tit"]

    //div[@class="threadlist_title pull_left j_th_tit"]

    //span[@class="frs-author-name-wrap"]

    2.2 属性部分匹配

    格式如下:

    标签名[contains(@属性名, 属性值)]

    比如:

    //a[contains(@class, "frs-author-name")]

    //div[contains(@class, "threadlist_title")]

    3 获取属性

    格式如下:

    标签名/@属性名

    获取到属性对于的值。比如:

    //a/@href

    //img/@src

    //div/img[@class="j_retract"]/@src

    4 获取内容

    格式如下:

    标签名/text()

    <a href=”xxx”>yyy</a>

    获取到内容对应的值,比如:

    //a/text()

    //a[@class="j_th_tit"]/text()

    8 案例:贴吧图片下载

    目标:访问贴吧。找出贴吧中每个帖子,根据链接进入帖子。找出帖子中的图片的链接地址。下载图片。

    8.1 获取页面

    from urllib import request, parse

    import ssl

    import random

    # 常用User-Agent列表

    ua_list = [

    'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',

    'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',

    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',

    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',

    'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',

    'Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'

    ]

    # 加载一个页面

    def loadPage(url):

    # ua_list列表中任意选择一个User-Agent

    userAgent = random.choice(ua_list)

    # 请求头

    headers = {

    'User-Agent' : userAgent

    }

    # 发送请求

    req = request.Request(url)

    # 创建一个未经过验证的上下文(避开系统的验证的步骤)

    context = ssl._create_unverified_context()

    # 打开响应的对象

    response = request.urlopen(req, context = context)

    # 获取网页的内容

    html = response.read()

    # unicode编码进行解码

    content = html.decode('utf-8')

    print(content)

    if __name__ == '__main__':

    url = 'https://tieba.baidu.com/f?kw=%E6%9F%AF%E5%8D%97&pn=50'

    loadPage(url)

    8.2 找出帖子链接地址

    python中使用xpath规则,需要安装LXML

    pip install lxml

    pip install lxml –i http://pypi.douban.com/simple --trusted-host pypi.douban.com

    在代码中使用lxml

    from urllib import request, parse

    import ssl

    import random

    from lxml import etree

    # 加载一个页面

    def loadPage(url):

    # ua_list列表中任意选择一个User-Agent

    userAgent = random.choice(ua_list)

    # 请求头

    headers = {

    'User-Agent' : userAgent

    }

    # 发送请求

    req = request.Request(url)

    # 创建一个未经过验证的上下文(避开系统的验证的步骤)

    context = ssl._create_unverified_context()

    # 打开响应的对象

    response = request.urlopen(req, context = context)

    # 获取网页的内容

    html = response.read()

    # unicode编码进行解码

    content = html.decode('utf-8')

    #print(content)

    # 使用etree来对html的内容建立文档树

    content = etree.HTML(content)

    link_list = content.xpath('//a[contains(@class,"j_th_tit")]/@href')

    for link in link_list:

    fulllink = 'https://tieba.baidu.com' + link

    print(fulllink)

     

    8.3 找出帖子中图片的链接

    # 加载一个页面

    def loadPage(url):

    …………

    # 使用etree来对html的内容建立文档树

    content = etree.HTML(content)

    link_list = content.xpath('//a[contains(@class,"j_th_tit")]/@href')

    for link in link_list:

    fulllink = 'https://tieba.baidu.com' + link

    #print(fulllink)

    loadImage(fulllink)

    # 加载帖子中的图片的链接

    def loadImage(url):

    # ua_list列表中任意选择一个User-Agent

    userAgent = random.choice(ua_list)

    # 请求头

    headers = {

    'User-Agent' : userAgent

    }

    # 发送请求

    req = request.Request(url, headers = headers)

    # 创建一个未经过验证的上下文(避开系统的验证的步骤)

    context = ssl._create_unverified_context()

    # 打开响应的对象

    response = request.urlopen(req, context = context)

    # 获取网页的内容

    html = response.read()

    # unicode编码进行解码

    content = html.decode('utf-8')

    # 使用etree来对html的内容建立文档树

    content = etree.HTML(content)

    link_list = content.xpath('//img[@class="BDE_Image"]/@src')

    for link in link_list:

    print(link)

    8.4 把图片保存到文件中

    # 加载帖子中的图片的链接

    def loadImage(url):

    …………

    # 使用etree来对html的内容建立文档树

    content = etree.HTML(content)

    link_list = content.xpath('//img[@class="BDE_Image"]/@src')

    for link in link_list:

    print(link)

    writeImage(link)

    # 下载图片并保存到本地文件中

    def writeImage(url):

    # ua_list列表中任意选择一个User-Agent

    userAgent = random.choice(ua_list)

    # 请求头

    headers = {

    'User-Agent' : userAgent

    }

    # 发送请求

    req = request.Request(url, headers = headers)

    # 创建一个未经过验证的上下文(避开系统的验证的步骤)

    context = ssl._create_unverified_context()

    # 打开响应的对象

    response = request.urlopen(req, context = context)

    # 获取网页的内容

    image = response.read()

    filename = url[-15:]

    f = open('img/' + filename, 'wb')

    f.write(image)

    f.close()

    8.5 用户输入参数

    def tiebaSpider(url, beginPage, endPage):

    for page in range(beginPage, endPage + 1):

    pn = (page-1)*50

    url += '&pn=' + str(pn)

    loadPage(url)

    if __name__ == '__main__':

    kw = input('请输入要爬取的贴吧:')

    beginPage = int(input('请输入起始页:'))

    endPage = int(input('请输入终止页:'))

    # 把用户输入的中文通过urlencode进行编码

    key = parse.urlencode({'kw':kw})

    url = 'https://tieba.baidu.com/f?' + key

    tiebaSpider(url, beginPage, endPage)

    9 selenium自动化工具

    9.1 安装selenium插件

    pip install selenium

    pip install selenium -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

    9.2 安装phantomjs无界面浏览器

    解压phantomjs压缩包,把bin所在的目录添加到环境变量PATH路径下。

     

    重启命令行cmd,确保输入phantomjs可以进入phantomjs命令行

     

    9.3 访问百度首页

    # 导入selenium工具

    from selenium import webdriver

    # 加载浏览器

    driver = webdriver.PhantomJS()

    # 用浏览器打开网页

    driver.get('https://www.baidu.com/')

    # 截图

    driver.save_screenshot('baidu1.png')

    现在,浏览器访问百度首页的图片保存到baidu1.png中了。

    9.4 进行搜索

    # 导入selenium工具

    from selenium import webdriver

    # 加载浏览器

    driver = webdriver.PhantomJS()

    # 用浏览器打开网页

    driver.get('https://www.baidu.com/')

    # 截图

    driver.save_screenshot('baidu1.png')

    # 进行搜索

    driver.find_element_by_id('kw').send_keys('古天乐')

    # 截图

    driver.save_screenshot('baidu2.png')

     

    # 点击百度一下

    driver.find_element_by_id('su').click()

    # 延迟1秒 稍等一下

    import time

    time.sleep(1)

    # 截图

    driver.save_screenshot('baidu3.png')

     

    9.5 ChromeDriver

    如果Selenium要和主流的浏览器关联,对应的浏览器需要安装驱动

    比如:通过seleniumChrome关联,Chrome需要安装ChromeDriver的驱动

     

     

    比如,Chrome版本是49的,对应的ChromeDriver可以选择v2.21v2.22

    可以在 http://chromedriver.storage.googleapis.com/index.html 下载对应的版本

    下载后进行解压,并把解压后的文件chromedriver.exe拷贝到Chrome的安装目录下。

    比如:C:UsersstuAppDataLocalGoogleChromeApplication

    然后,修改上面的selenium的代码。把原先是通过PhantomJS浏览器打开的网页改为通过Chrome打开。

    # 加载浏览器

    #driver = webdriver.PhantomJS()

    driver = webdriver.Chrome()

    10 虎牙直播

    URL为:https://www.huya.com/l 

    留意:该URL当翻页的时候,并没有变化。不能按之前的方式去爬

    此时,考虑使用自动化的方法模拟“点击”下一页按钮,每翻一页,就爬一页的数据。

    目标:

    1 直播房间数量

    2 人气总数

    10.1 xpath规则

    找房间

    //ul[@id="js-live-list"]/li[@class="game-live-item"]

    房间的名称

    //ul[@id="js-live-list"]/li[@class="game-live-item"]/a[contains(@class, "title")]/text()

    ./a[contains(@class, "title")]/text()

    房间的人气

    //ul[@id="js-live-list"]/li[@class="game-live-item"]/span[@class="txt"]/span[@class="num"]/i[@class="js-num"]/text()

    ./span[@class="txt"]/span[@class="num"]/i[@class="js-num"]/text()

    10.2 环境搭建

    # 导入selenium工具

    from selenium import webdriver

    class Huya(object):

    # 初始化

    def __init__(self):

    # 加载浏览器

    self.driver = webdriver.PhantomJS()

    # 统计的数量

    self.room_count = 0 # 直播房间数量

    self.room_hot = 0 # 人气总数

    # 执行爬虫

    def run(self):

    # 打开网页

    self.driver.get('https://www.huya.com/l')

    # 爬取相关的内容

    # TODO 一会儿再做

    # 输出结果

    print('当前直播房间数量:', self.room_count)

    print('当前人气总数:', self.room_hot)

    if __name__ == '__main__':

    huya = Huya()

    huya.run()

    10.3 爬取首页数据

    # 导入selenium工具

    from selenium import webdriver

    # 导入lxml的库

    from lxml import etree

    # 执行爬虫

    def run(self):

    # 打开网页

    self.driver.get('https://www.huya.com/l')

    # 爬取相关的内容

    content = etree.HTML(self.driver.page_source) # 获取并构建网页的内容

    # 获取房间的信息

    rooms = content.xpath('//ul[@id="js-live-list"]/li[@class="game-live-item"]')

    for room in rooms:

    roomname = ''

    tmp = room.xpath('./a[contains(@class, "title")]/text()')

    if len(tmp) > 0:

    roomname = tmp[0]

    hot = '0'

    tmp = room.xpath('./span[@class="txt"]/span[@class="num"]/i[@class="js-num"]/text()')

    if len(tmp) > 0:

    hot = tmp[0]

    print('房间人气:' +  hot + ' ' + '房间名称:' + roomname)

    # 输出结果

    print('当前直播房间数量:', self.room_count)

    print('当前人气总数:', self.room_hot)

    10.4 统计首页的数据

    # 执行爬虫

    def run(self):

    # 打开网页

    self.driver.get('https://www.huya.com/l')

    # 爬取相关的内容

    content = etree.HTML(self.driver.page_source) # 获取并构建网页的内容

    # 获取房间的信息

    rooms = content.xpath('//ul[@id="js-live-list"]/li[@class="game-live-item"]')

    for room in rooms:

    roomname = ''

    tmp = room.xpath('./a[contains(@class, "title")]/text()')

    if len(tmp) > 0:

    roomname = tmp[0]

    hot = '0'

    tmp = room.xpath('./span[@class="txt"]/span[@class="num"]/i[@class="js-num"]/text()')

    if len(tmp) > 0:

    hot = tmp[0]

    print('房间人气:' +  hot + ' ' + '房间名称:' + roomname)

    # 增加房间的数量

    self.room_count += 1

    # 增加人气的数量

    if hot[-1] == '':

    hot = hot[:-1] # '18.1' --- '18.1'

    hot = int(float(hot) * 10000) # '18.1' --- 181000

    self.room_hot += hot

    else:

    self.root_hot += int(hot) # '18' --- 18

    # 输出结果

    print('当前直播房间数量:', self.room_count)

    print('当前人气总数:', self.room_hot)

    10.5 尝试翻页

    当有“下一页”按钮的时候,可以找到class="laypage_next"

     

    当没有“下一页”按钮的时候,找不到class="laypage_next"

     

    可以使用find("laypage_next")查找是否有这个元素

    # 测试翻页的效果

    def test(self):

    # 打开网页

    self.driver.get('https://www.huya.com/l')

    # 循环遍历每一页

    page = 0

    while True:

    # 延时1

    import time

    time.sleep(1)

    page += 1

    ret = self.driver.page_source.find('laypage_next')

    if ret > 0: # 找到

    print('' + str(page) + '')

    else: # 找不到

    print('最后一页')

    break

    # 点击下一页按钮

    self.driver.find_element_by_class_name('laypage_next').click()

    if __name__ == '__main__':

    huya = Huya()

    #huya.run()

    huya.test()

    10.6 爬取多页

    结合10.4统计一页的数据,和10.5循环翻页的功能。整合出最终的爬虫程序,爬取所有的页面,并统计出结果。

    END

  • 相关阅读:
    JS阻止鼠标滚动
    仿淘宝订单列表下标指针
    自己动手模拟百分百<select>下拉列表
    专门用来存地址
    JS手动触发事件,转载
    刷新页面让显示区域回到顶部
    解决表格边框问题
    读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字
    读书笔记 effective c++ Item 42 理解typename的两种涵义
    读书笔记 effective c++ Item 41 理解隐式接口和编译期多态
  • 原文地址:https://www.cnblogs.com/wangprince2017/p/13708653.html
Copyright © 2011-2022 走看看