欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络爬虫2

程序员文章站 2022-05-04 11:28:18
...

网络爬虫2

正则

  • re.match():从头开始匹配
  • re.search():不从头开始匹配
  • re.spilt():切割,返回列表参数maxsplit指定最大的切割数,默认全部
  • re.findall():以列表形式返回能匹配的全部字符串
  • re.finditer():功能与上相同,但返回的是一个迭代器

BeautifulSoup

  • 可以从HTML或XML文件中提取数据的Python库

  • 安装:

    apt-get install Python-bs4
    # 或
    pip install beautifulsoup4
    # lxml安装
    pip install lxml
    
  • 使用

    • 导入模块

      from bs4 import BeautifulSoup as Bs
      
    • 创建对象:

      • 字符串创建

        soup = Bs(html_str,'lxml',from_encoding='utf-8')
        
      • html文件创建

        soup = Bs(open('index.html'))
        
    • 利用soup加标记名就可以获取这些标记的内容,但只是第一个

      • soup.title:输出的是第一个title标签
      • soup.title.name:第一个title标签的名字
      • soup.p['class']:第一个P标签的class属性(多个属性则返回一个列表)
      • soup.p.get('class'):与上一样
      • soup.p.string:第一个p标签的内容

数据存储

  • JSON写入

    import json
    str = [{"name":"范晓昊","age":18."gender":"男"}]
    with open('json_str.json','w') as f:
        f.write(json.dumps(str,indent=2,ensure_ascii=Flase))
    
  • JSON读取

    json.loads(str)  # 可以把json字符串转化成Python对象(列表)
    
  • csv写入(字典写入)

    import csv
    titles = ['name','age']
    rows = [{'name':'范晓昊','age':18},
           {'naem':'李二狗''age':19}]
    with open('csvfile.csv','w',newline='',encoding='utf-8') as f:
        f_csv = csv.DictWriter(f,titles)  # 获取文件”写笔“,此时并不会重写标题
        f_csv.writeheader()  # 写入记录标题
        f_csv.writerows()  # 写入多行记录
    
  • csv写入(列表写入)

    import csv
    title = ['name':'age']
    rows = [("范晓昊",21),
           ("李二狗",20)]
    with open("csvfile.csv",'w',newlone='',encoding='utf-8') as f:
        f_csv = csv.writer(f)
        f_csv.wirterow(titles)
        f_csv.writerows(rows)
    
  • csv读取(字典读取)

    import csv
    with open('data.csv','r') as f:
        reader = csv.DictReader(f)
        for i in reader:
            name = i["name"]
            age = i["age"]
            print({"name":name,"age":age})
    
    
  • csv读取(列表读取)

    import csv
    with open('data.csv','r') as f:
        reader = csv.reader(f)   # 返回读取迭代器
        titles = next(reader)   # 提取文件记录标题
        for i in reader:  # 遍历向下迭代
            name = i[0]
            age = i[1]
            print({"name":name,"age":age})
    
    

多媒体文件存储

  • 一种是获取URL链接存储

    一种是直接下载到本地

  • urllib模块中的urlretrieve() 可将数据下载到本地(urllib.request中)

    def report(count, blockSize, totalSize):
                '''回调函数,一行显示进度条'''
                percent = int(count * blockSize * 100 / totalSize)
                sys.stdout.write("\r%d%%" % percent + ' complete')
                sys.stdout.write('[%-50s] %s' % ('=' * int(math.floor(count * blockSize * 50 / totalSize)), percent))
                sys.stdout.flush()
                
    urlretrieve(video_url,video_name, report)
    
    

urlparse模块

  • urlparse.urlparse():将url分为6个部分,返回一个包含6个字符串项目的元组
  • urlparse.urljoin():将相对地址组合成一个url,对输入没什么限制,但开头必须是协议

selenium与phantomJS

  • selenium是一个web的自动化测试工具,可以通过命令来自动操作(需要下载对应浏览器的driver)

    • 可以通过pip install 来安装
  • phantomJS是一款*面的浏览器

  • 使用

    from selenium import webdiver
    
    # 实例化一个浏览器
    driver = webdriver.Chrome('./chromedriver')  # 也可以直接放在user/bin或user/local/bin下
    # 发送请求
    driver.get('url')
    # 退出浏览器
    diver.quit()
    
    
  • 注意

    • 获取文本和获取属性时:先定位到元素,然后调用.txt或者get_attribute方法来获取
    • selenium获取的页面数据时浏览器中的elements的内容
    • find_elementfind_elements
      • 前者返回一个element,如果没有就会报错
      • 后者返回一个列表,没有就为空列表
    • 在判断下一页的时候,使用find_elements来根据结果的列表判断
      • 如果页面中包含iframeframe,需要先调用driver.switch_to.frame的方法切换到frame中才能定位元素(传ID:name)
    • selenium请求第一页的时候会等待页面加载完之后再获取数据,但是在点击翻页之后,会直接马上获取数据,此时可能会报错,因为数据还没有加载出来,需要time.sleep

数据去重

  • 使用数据库建立关键字段(一个或多个)建立索引进行去重
  • 根据url地址去重
    • 使用场景:url地址对应的数据不会变的情况,url地址能够唯一判别一个数据的情况
    • 思路:url存在redis中
      • 拿到url地址,判断url在Redis的url集合中是否存在
        • 存在:说明url已经被爬取过,不需在请求
        • 不存在:没有的话,就请求,然后把该url存入Redis的集合中
      • 布隆过滤器:
  • 根据数据本身去重
    • 选择特定的字段,使用加密算法(md5、shal)将字段进行加密,生成字符串,存入Redis的集合中
    • 后续新来一条数据,同样的方法加密,在与Redis中的字符串对比,如果相同则存在,选择更新或pass,否则数据不存在,直接插入

END。