python爬虫学习(七)

python爬虫学习(六)回顾

多线程爬虫

  • 思路

    1】将待爬取的URL地址存放到队列中
    【2】多个线程从队列中获取地址,进行数据抓取
    【3】注意获取地址过程中程序阻塞问题、线程锁问题
        3.1) 方式一
        while True:
            lock.acquire()
            if not q.empty():
                url = q.get()
                lock.release()
                ... ... 
            else:
                lock.release()
                break
            
        3.2) 方式二->【多级页面数据抓取所需】
        while True:
            try:
                lock.acquire()
                url = q.get(block=True,timeout=3)
                lock.release()
                ... ... 
            except Exception as e:
                lock.release()
                break4】注意: 使用多线程爬取多级页面
        4.1) 创建对应队列,用来存储不同级页面的URL地址
        4.2) 除一级页面队列外,其他队列获取地址均采用如下方式
             url = q.get(block=True,timeout=2)
    

解析模块汇总

  • re、lxml+xpath、json

    1】re
        import re
        pattern = re.compile(r'',re.S)
        r_list = pattern.findall(html)2】lxml+xpath
        from lxml import etree
        parse_html = etree.HTML(html)
        r_list = parse_html.xpath('')3】json
        3.1) 响应内容由json转为python : html = json.loads(res.text) 
        3.2) 所抓数据保存到json文件
            with open('xxx.json','a') as f:
                json.dump(item_list,f,ensure_ascii=False)
    

selenium+phantomjs | chrome | firefox

  • 特点

    1】简单,无需去详细抓取分析网络数据包,使用真实浏览器
    【2】需要等待页面元素加载,需要时间,效率低
    
  • 安装

    1】下载、解压
    
    【2】添加到系统环境变量
        2.1) windows: 拷贝到Python安装目录的Scripts目录中
        2.2) Linux :  拷贝到/usr/bin目录中 : sudo cp chromedriver /usr/bin/3】Linux中需要修改权限(主要是添加x权限)
        sudo chmod 777 /usr/bin/chromedriver
        sudo chmod +x /usr/bin/chromedriver
    
  • 使用流程

    from selenium import webdriver
    
    # 1、创建浏览器对象
    browser = webdriver.Firefox(executable_path='/xxx/geckodriver')
    # 2、输入网址
    browser.get('URL')
    # 3、查找节点
    brower.find_xxxx
    # 4、做对应操作
    element.send_keys('')
    element.click()
    # 5、关闭浏览器
    browser.quit()
    

Python爬虫学习(七)

selenium+PhantomJS|Chrome|Firefox

  • 浏览器对象(browser)方法

    1、browser = webdriver.Chrome(executable_path='path')
    2、browser.get(url)
    3、browser.page_source # HTML结构源码
    4、browser.page_source.find('字符串')
       # 从html源码中搜索指定字符串,没有找到返回:-1
    5、browser.close() # 关闭当前页
    6、browser.quit() # 关闭浏览器
    
  • 定位节点

    # 1、单元素查找(1个节点对象)
    1、browser.find_element_by_id('')
    2、browser.find_element_by_name('')
    3、browser.find_element_by_class_name('')
    4、browser.find_element_by_xpath('')
    5、browser.find_element_by_link_text('')
    ... ...
    
    # 2、多元素查找([节点对象列表])
    1、browser.find_elements_by_id('')
    2、browser.find_elements_by_name('')
    3、browser.find_elements_by_class_name('')
    4、browser.find_elements_by_xpath('')
    ... ...
    
  • 节点对象操作

    1、ele.send_keys('') # 搜索框发送内容
    2、ele.click()
    3、ele.text # 获取文本内容,包含子节点和后代节点的文本内容
    4、ele.get_attribute('src') # 获取属性值
    
  • chromedriver设置无界面模式

    from selenium import webdriver
    
    options = webdriver.ChromeOptions()
    # 添加无界面参数
    options.add_argument('--headless')
    browser = webdriver.Chrome(options=options)
    

京东爬虫

  • 目标

    1】目标网址 :https://www.jd.com/2】抓取目标 :商品名称、商品价格、评价数量、商品商家
    
  • 思路提醒

    1】打开京东,到商品搜索页
    【2】匹配所有商品节点对象列表
    【3】把节点对象的文本内容取出来,查看规律,是否有更好的处理办法?
    【4】提取完1页后,判断如果不是最后1页,则点击下一页
        '问题: 如何判断是否为最后1页???'
    
  • 实现步骤

    1】找节点
        1.1) 首页搜索框 : //*[@id="key"]
        2.1) 首页搜索按钮   ://*[@id="search"]/div/div[2]/button
        2.3) 商品页的 商品信息节点对象列表 ://*[@id="J_goodsList"]/ul/li
        2.4) for循环遍历后
            a> 名称: .//div[@class="p-name"]/a/em
            b> 价格: .//div[@class="p-price"]
            c> 评论: .//div[@class="p-commit"]/strong
            d> 商家: .//div[@class="p-shopnum"]2】执行JS脚本,获取动态加载数据
        browser.execute_script(
          'window.scrollTo(0,document.body.scrollHeight)'
        )
    
  • 代码实现

    from selenium import webdriver
    import time
    
    class JdSpider(object):
        def __init__(self):
            self.url = 'https://www.jd.com/'
            # 设置无界面模式
            self.options = webdriver.ChromeOptions()
            self.options.add_argument('--headless')
            self.browser = webdriver.Chrome(options=self.options)
    
        def get_html(self):
            # get():等页面所有元素加载完成后,才会执行后面的代码
            self.browser.get(self.url)
            # 搜索框 + 搜索按钮
            self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书')
            self.browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
    
        # 循环体中的函数: 拉进度条,提取数据
        def parse_html(self):
            # 执行js脚本,将进度条拉到最底部
            self.browser.execute_script(
                'window.scrollTo(0,document.body.scrollHeight)'
            )
            # 给页面元素加载预留时间
            time.sleep(3)
            li_list = self.browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
    
            for li in li_list:
                item = {}
                item['price'] = li.find_element_by_xpath('.//div[@class="p-price"]').text
                item['mame'] = li.find_element_by_xpath('.//div[@class="p-name"]/a/em').text
                item['commit'] = li.find_element_by_xpath('.//div[@class="p-commit"]/strong').text
                item['shop'] = li.find_element_by_xpath('.//div[@class="p-shopnum"]').text
                print(item)
    
        def run(self):
            self.get_html()
            while True:
                self.parse_html()
                if self.browser.page_source.find('pn-next disabled') == -1:
                    self.browser.find_element_by_xpath('//*[@id="J_bottomPage"]/span[1]/a[9]').click()
                else:
                    self.browser.quit()
                    break
    
    if __name__ == '__main__':
        spider = JdSpider()
        spider.run()
    

selenium - 键盘操作

from selenium.webdriver.common.keys import Keys

browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')
# 1、在搜索框中输入"selenium"
browser.find_element_by_id('kw').send_keys('赵丽颖')
# 2、输入空格
browser.find_element_by_id('kw').send_keys(Keys.SPACE)
# 3、Ctrl+a 模拟全选
browser.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')
# 4、Ctrl+c 模拟复制
browser.find_element_by_id('kw').send_keys(Keys.CONTROL, 'c')
# 5、Ctrl+v 模拟粘贴
browser.find_element_by_id('kw').send_keys(Keys.CONTROL, 'v')
# 6、输入回车,代替 搜索 按钮
browser.find_element_by_id('kw').send_keys(Keys.ENTER)

selenium - 鼠标操作

from selenium import webdriver
# 导入鼠标事件类
from selenium.webdriver import ActionChains

driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')

# 移动到 设置,perform()是真正执行操作,必须有
element = driver.find_element_by_xpath('//*[@id="u1"]/a[8]')
ActionChains(driver).move_to_element(element).perform()

# 单击,弹出的Ajax元素,根据链接节点的文本内容查找
driver.find_element_by_link_text('高级搜索').click()

selenium - 切换页面

  • 适用网站+应对方案

    1】适用网站类型
        页面中点开链接出现新的页面,但是浏览器对象browser还是之前页面的对象
        
    【2】应对方案 - browser.switch_to.window()
        # 获取当前所有句柄(窗口)- [handle1,handle2]
        all_handles = browser.window_handles
        # 切换browser到新的窗口,获取新窗口的对象
        browser.switch_to.window(all_handles[1])
    
  • 民政部网站案例-selenium

    """
    适用selenium+Chrome抓取民政部行政区划代码
    http://www.mca.gov.cn/article/sj/xzqh/2019/
    """
    from selenium import webdriver
    
    class GovSpider(object):
        def __init__(self):
            # 设置无界面
            options = webdriver.ChromeOptions()
            options.add_argument('--headless')
            # 添加参数
            self.browser = webdriver.Chrome(options=options)
            self.one_url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
    
        def get_incr_url(self):
            self.browser.get(self.one_url)
            # 提取最新链接节点对象并点击
            self.browser.find_element_by_xpath('//td[@class="arlisttd"]/a[contains(@title,"代码")]').click()
            # 切换句柄
            all_handlers = self.browser.window_handles
            self.browser.switch_to.window(all_handlers[1])
            self.get_data()
    
        def get_data(self):
            tr_list = self.browser.find_elements_by_xpath('//tr[@height="19"]')
            for tr in tr_list:
                code = tr.find_element_by_xpath('./td[2]').text.strip()
                name = tr.find_element_by_xpath('./td[3]').text.strip()
                print(name,code)
    
        def run(self):
            self.get_incr_url()
            self.browser.quit()
    
    if __name__ == '__main__':
      spider = GovSpider()
      spider.run()
    

selenium - iframe子框架

  • 特点+方法

    1】特点
        网页中嵌套了网页,先切换到iframe子框架,然后再执行其他操作
        
    【2】方法
        browser.switch_to.frame(iframe_element)
    
  • 示例1 - 登录豆瓣网

    """
    登录豆瓣网
    """
    from selenium import webdriver
    import time
    
    # 打开豆瓣官网
    browser = webdriver.Chrome()
    browser.get('https://www.douban.com/')
    
    # 切换到iframe子页面
    login_frame = browser.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
    browser.switch_to.frame(login_frame)
    
    # 密码登录 + 用户名 + 密码 + 登录豆瓣
    browser.find_element_by_xpath('/html/body/div[1]/div[1]/ul[1]/li[2]').click()
    browser.find_element_by_xpath('//*[@id="username"]').send_keys('15110225726')
    browser.find_element_by_xpath('//*[@id="password"]').send_keys('zhanshen001')
    browser.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
    time.sleep(3)
    
    # 点击我的豆瓣
    browser.find_element_by_xpath('//*[@id="db-nav-sns"]/div/div/div[3]/ul/li[2]/a').click()
    
  • 示例2-登录QQ邮箱

    from selenium import webdriver
    import time
    
    driver = webdriver.Chrome()
    driver.get('https://mail.qq.com/')
    
    # 切换到iframe子框架
    driver.switch_to.frame("login_frame")
    
    # 用户名+密码+登录
    driver.find_element_by_id('u').send_keys('2621470058')
    driver.find_element_by_id('p').send_keys('zhanshen001')
    driver.find_element_by_id('login_button').click()
    
  • selenium+phantomjs|chrome|firefox小总结

    1】设置无界面模式
        options = webdriver.ChromeOptions()
        options.add_argument('--headless')
        browser = webdriver.Chrome(excutable_path='/home/tarena/chromedriver')2】browser执行JS脚本
        browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')3】键盘操作
        from selenium.webdriver.common.keys import Keys
        
    【4】鼠标操作
        from selenium.webdriver import ActionChains
        ActionChains(browser).move_to_element('node').perform()5】切换句柄 - switch_to.frame(handle)
        all_handles = browser.window_handles
        browser.switch_to.window(all_handles[1])
        # 开始进行数据抓取
        browser.close()
        browser.switch_to.window(all_handles[0])6】iframe子页面
        browser.switch_to.frame(iframe_node)
    
  • lxml中的xpath 和 selenium中的xpath的区别

    1】lxml中的xpath用法 - 推荐自己手写
        div_list = p.xpath('//div[@class="abc"]/div')
        item = {}
        for div in div_list:
            item['name'] = div.xpath('.//a/@href')[0]
            item['likes'] = div.xpath('.//a/text()')[0]2】selenium中的xpath用法 - 推荐copy - copy xpath
        div_list = browser.find_elements_by_xpath('//div[@class="abc"]/div')
        item = {}
        for div in div_list:
            item['name'] = div.find_element_by_xpath('.//a').get_attribute('href')
            item['likes'] = div.find_element_by_xpath('.//a').text
    

scrapy框架

  • 定义

    异步处理框架,可配置和可扩展程度非常高,Python中使用最广泛的爬虫框架
    
  • 安装

    1】Ubuntu安装
        1.1) 安装依赖包
            a> sudo apt-get install libffi-dev
            b> sudo apt-get install libssl-dev
            c> sudo apt-get install libxml2-dev
            d> sudo apt-get install python3-dev
            e> sudo apt-get install libxslt1-dev
            f> sudo apt-get install zlib1g-dev
            g> sudo pip3 install -I -U service_identity
            
        1.2) 安装scrapy框架
            a> sudo pip3 install Scrapy
            
    【2】Windows安装
        2.1) cmd命令行(管理员): python -m pip install Scrapy
       【注意】: 如果安装过程中报如下错误
                'Error: Microsoft Vistual C++ 14.0 is required xxx'
                则安装Windows下的Microsoft Vistual C++ 14.0 即可(笔记spiderfiles中有)
    
  • Scrapy框架五大组件

    1】引擎(Engine)      :整个框架核心
    【2】调度器(Scheduler) :维护请求队列
    【3】下载器(Downloader):获取响应对象
    【4】爬虫文件(Spider)  :数据解析提取
    【5】项目管道(Pipeline):数据入库处理
    **********************************
    【中间件1: 下载器中间件(Downloader Middlewares) : 引擎->下载器,包装请求(随机代理等)
    【中间件2: 蜘蛛中间件(Spider Middlewares) : 引擎->爬虫文件,可修改响应对象属性
    
  • scrapy爬虫工作流程

    1】爬虫项目启动,由引擎向爬虫程序索要第一批要爬取的URL,交给调度器去入队列
    【2】调度器处理请求后出队列,通过下载器中间件交给下载器去下载
    【3】下载器得到响应对象后,通过蜘蛛中间件交给爬虫程序
    【4】爬虫程序进行数据提取:
        4.1) 数据交给管道文件去入库处理
        4.2) 对于需要继续跟进的URL,再次交给调度器入队列,依次循环
    
  • scrapy常用命令

    1】创建爬虫项目
        scrapy startproject 项目名
        
    【2】创建爬虫文件
        scrapy genspider 爬虫名 域名
        
    【3】运行爬虫
        scrapy crawl 爬虫名
    
  • scrapy项目目录结构

    Baidu                   # 项目文件夹
    ├── Baidu               # 项目目录
    │   ├── items.py        # 定义数据结构
    │   ├── middlewares.py  # 中间件
    │   ├── pipelines.py    # 数据处理
    │   ├── settings.py     # 全局配置
    │   └── spiders
    │       ├── baidu.py    # 爬虫文件
    └── scrapy.cfg          # 项目基本配置文件
    
  • settings.py常用变量

    1】USER_AGENT = 'Mozilla/5.0'2】ROBOTSTXT_OBEY = False
        是否遵循robots协议,一般我们一定要设置为False3】CONCURRENT_REQUESTS = 32
        最大并发量,默认为164】DOWNLOAD_DELAY = 0.5
        下载延迟时间: 访问相邻页面的间隔时间,降低数据抓取的频率
    
    【5】COOKIES_ENABLED = False | True
        Cookie默认是禁用的,取消注释则 启用Cookie,即:TrueFalse都是启用Cookie
        
    【6】DEFAULT_REQUEST_HEADERS = {}
        请求头,相当于requests.get(headers=headers)
    
  • 安装scrapy出现问题

    xxx has requirement 模块>=4.4.2 but you'll have 模块 4.3.2
    升级模块: sudo pip3 install 模块 --upgrade
    

小试牛刀

1】执行3条命令,创建项目基本结构
    scrapy startproject Baidu
    cd Baidu
    scrapy genspider baidu www.baidu.com
    
【2】完成爬虫文件: spiders/baidu.py
    import scrapy
    class BaiduSpider(scrapy.Spider):
        name = 'baidu'
        allowed_domains = ['www.baidu.com']
        start_urls = ['http://www.baidu.com/']
        
        def parse(self,response):
            r_list = response.xpath('/html/head/title/text()').extract()[0]
            print(r_list)3】完成settings.py配置
    3.1) ROBOTSTXT_OBEY = False
    3.2) DEFAULT_REQUEST_HEADERS = {
        'User-Agent' : 'Mozilla/5.0'
    }4】运行爬虫
    4.1) 创建run.py(和scrapy.cfg同路径)
    4.2) run.py
         from scrapy import cmdline
         cmdline.execute('scrapy crawl baidu'.split())5】执行 run.py 运行爬虫

今日作业(八里面会有答案哦)

1】使用selenium+浏览器 获取有道翻译结果
【2】使用selenium+浏览器 登录网易qq邮箱 : https://mail.qq.com/3】使用selenium+浏览器 登录网易163邮箱 : https://mail.163.com/4】熟记scrapy的五大组件,以及工作流程,能够描述的很清楚
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大枫free

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值