zoukankan      html  css  js  c++  java
  • 爬虫进阶

    利用多线程爬取数据

    import threading
    import requests
    from lxml import etree
    from urllib import request
    import os
    import re
    from queue import Queue
    
    class HtmlSprider(threading.Thread):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
        }
        def __init__(self,page_queue,img_queue,*args,**kwargs):
            super(HtmlSprider, self).__init__(*args,**kwargs)
            self.page_queue = page_queue
            self.img_queue = img_queue
    
    
        def run(self):
            while True:
                if self.page_queue.empty():
                    break
                url = self.page_queue.get()
                self.parse_page(url)
    
        def parse_page(self,url):
            response = requests.get(url,headers=self.headers)
            text = response.text
            html = etree.HTML(text)
            imgs = html.xpath("//div[@class='page-content text-center']//a//img")
            for img in imgs:
                if img.get('class') == 'gif':
                    continue
                img_url = img.xpath(".//@data-original")[0]
                suffix = os.path.splitext(img_url)[1]
                suffix = re.sub(r"!dta", "", suffix)
                alt = img.xpath(".//@alt")[0]
                alt = re.sub(r'[,。??,/\·]','',alt)
                img_name = alt + suffix
                self.img_queue.put((img_url,img_name))
    
    class DownloadPicture(threading.Thread):
        def __init__(self,page_queue,img_queue,*args,**kwargs):
            super(DownloadPicture, self).__init__(*args,**kwargs)
            self.page_queue = page_queue
            self.img_queue = img_queue
    
        def run(self):
            while True:
                if self.img_queue.empty():
                    if self.page_queue.empty():
                        return
                img = self.img_queue.get(block=True)
                url,filename = img
                request.urlretrieve(url,'images/'+filename)
                print(filename+'  下载完成!')
    
    def main():
        page_queue = Queue(100)
        img_queue = Queue(500)
        for x in range(1,10):
            url = "http://www.doutula.com/photo/list/?page=%d" % x
            page_queue.put(url)
    
        for x in range(5):
            t = HtmlSprider(page_queue,img_queue)
            t.start()
    
        for x in range(5):
            t = DownloadPicture(page_queue,img_queue)
            t.start()
    
    if __name__ == '__main__':
        main()
    

    爬取动态数据

    AJAX(Asynchronouse JavaScript And XML),翻译为异步JavaScript和XML。是在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。我们有两种办法来处理这种情况:

    1. 直接分析ajax调用的接口。这样虽然代码量小,不过需要很深的js功底,要不然极容易被发现是爬虫。
    2. 使用seleniumchromedriver来模拟登陆。这样虽然繁琐,不过很稳定。Selenium相当于是一个机器人。可以模拟人类在浏览器上的一些行为,自动处理浏览器上的一些行为,比如点击,填充数据,删除cookie等。chromedriver是一个驱动Chrome浏览器的驱动程序,使用他才可以驱动浏览器。

    selenium快速入门与基本操作

    selenium文档官网

    from selenium import webdriver
    import time
    
    driver_path = "D:\chromedriver\chromedriver.exe" ##获取chromedriver可执行文件的地址
    inputTag = webdriver.Chrome(executable_path=driver_path) ##传入chromedriver地址
    inputTag.get("http://www.baidu.com")  ##访问页面
    inputTag = inputTag.find_element_by_id("kw")
    inputTag.send_keys("python")
    time.sleep(4)
    

    关闭页面

    • driver.close():关闭当前页面
    • driver.quit():退出浏览器

    定位元素

    • find_element_by_id:根据id来查找元素
    • find_element_by_class_name:根据类名查找元素
    • find_element_by_name:根据name属性的值来查找元素
    • find_element_by_tag_name:根据标签名来查找元素
    • find_element_by_xpath:根据xpath语法来获取元素
    • find_element_by_css_selector:根据css选择器选择元素

    注意:把以上方法中的element改为elements就可以获取所有相关元素了

    操作表单元素

    • 操作输入框
    #1.先获取需要填写内容的表单
    #2.用send_keys方法发送要输入的值
    inputTag = driver.find_element_by_id("kw") 
    inputTag.send_keys("python")
    
    • 清除输入框里面的内容
    inputTag.clear()
    
    • 操作点击
    rememberTag = driver.find_element_by_name("rememberMe")
    rememberTag.click()
    
    • 选择select标签
    
    
    • 鼠标相关其他操作
      • click_and_hold(element):点击但不松开鼠标
      • context_click(element):右键点击
      • double_click(element):双击

    行为链

    inputTag = driver.find_element_by_id('kw')
    submitTag = driver.find_element_by_id('su')
    ## 我们可以使用鼠标行为链类ActionChains来完成
    actions = ActionChains(driver)
    actions.move_to_element(inputTag)
    actions.send_keys_to_element(inputTag,'python')
    actions.move_to_element(submitTag)
    actions.click(submitTag)
    actions.perform()
    

    Cookie操作

    • 获取所有Cookie:
    for cookie in driver.get_cookies():
    	print(cookie
    
    • 根据cookie的key获取value:
    value = driver.get_cookie(key)
    
    • 删除所有Cookie:
    driver.delete_all_cookies()
    
    • 删除某个cookie:
    driver.delete_cookie(key)
    

    页面等待

    现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。因此,selenium提供了以下两种解决办法:

    隐式等待

    driver = webdriver.Chrome(executable_path=driver_path)
    driver.implicitly_wait(10)
    # 请求网页
    driver.get("https://www.baidu.com/")
    

    显示等待

    显示等待是表明某个条件成立后才执行获取元素的操作。也可以在等待的时候指定一个最大的时间,如果超过这个时间那么就抛出一个异常。

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    driver = webdriver.Firefox()
    driver.get("http://somedomain/url_that_delays_loading")
    try:
        element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "myDynamicElement"))
         )
    finally:
        driver.quit()
    

    一些其他的等待条件:

    • presence_of_element_located:某个元素已经加载完毕
    • presence_of_all_element_located:网页中所有满足条件的元素都加载完毕了
    • element_to_be_cliable:某个元素可以点击了

    切换页面

    from selenium import webdriver
    
    driver_path = r"D:chromedriverchromedriver.exe"
    driver = webdriver.Chrome(executable_path=driver_path)
    driver.get("https://baidu.com/")
    ##打开新的一个页面
    driver.execute_script("window.open('http://www.douban.com/')")
    ##切换到这个新的页面中
    driver.driver.switch_to.window(driver.window_handles[1])
    

    设置IP代理

    from selenium import webdriver
    
    options = webdriver.ChromeOptions()
    options.add_argument("--proxy-server=http://110.52.235.241:9999")
    driver_path = r"D:chromedriverchromedriver.exe"
    driver = webdriver.Chrome(executable_path=driver_path,options=options)
    driver.get("http://www.ip138.com/")
    

    图像验证码识别技术和tesseract

    tesseract安装与配置

    GIT官网

    设置系统变量

    在Windows下把tesseract.exe所在的路径添加到PATH环境变量中。还有一个环境变量需要设置的是,要把训练的数据文件路径也放到环境变量中。在环境变量中,添加一个TESSDATA_PREFIX=C:path_to_tesseractdata eseractdata。

    在cmd中使用

    tesseract 图片路径 文件路径
    

    文件路径不需要添加后缀名也会默认为.txt

    python代码中实现

    import pytesseract
    from PIL import Image
    ##获得tesseract可执行文件地址
    pytesseract.pytesseract.tesseract_cmd = r"D:	esseract	esseract.exe"
    ##利用该模块打开图片文件
    image = Image.open(r"C:UsersDELLDesktopa.png")
    ##image_to_string()方法转换成字符串
    text = pytesseract.image_to_string(image)
    print(text)
    
  • 相关阅读:
    css3
    ubuntu /mac 终端命令大全
    MarkDown的语法的简要规则
    向github上传一个项目
    datatable 去掉默认功能
    datatable 自定义筛选
    vuex
    es6入门教程
    datatable 指定添加排序,根据列的值来设置颜色
    在ios上块点击出现闪黑底
  • 原文地址:https://www.cnblogs.com/MingleYuan/p/10742379.html
Copyright © 2011-2022 走看看