zoukankan      html  css  js  c++  java
  • Python 爬虫实战(一)——requests+正则表达式 爬取猫眼TOP100

    一。思路:python 内置了两个网络库 urlib和urlib2,但是这两个库使用起来不是很方便,所以这里使用广受好评的第三库requests。 (基本思路使用requests获取页面信息,使用正则表达式解析页面,为了更加迅速的爬取数据,使用multiprocessing实现多进程抓取。下一篇文章会使用Beautifulsoup来解析页面。这篇文章主要用来记录一下代码过程中遇到的一点问题,关于各个模块的使用自行先熟悉。

        环境配置:我用的是Anaconda2 (python 2.7)

    二。Requests:

       1.request官方文档http://docs.python-requests.org/en/master/ 
        使用requests的get请求获得猫眼Top100的html。通过状态码来判断请求是否成功,如果请求不成功,那么返回None.用Requests的RequestException来捕捉异常:

    def get_one_page(url):
        try:
            response=requests.get(url)
            if response.status_code==200:
                response=response.text
                return response
            else:
                return None
        except RequestException:
            return None


       2.用正则表达式来解析这个页面。这里面主要用到 compile()和findall()这两个方法。 

              使用函数compile(pattern,flag) 进行预编译,把我们想要提取的index,title,actor等信息分别用子组来匹配中。findall()返回的是一个元组组成的列表,当正则表达式有多个子组的时候,元组中的每一个元素都是一个子模式的匹配内容。re.S这个参数是在字符串a中,包含换行符 ,在这种情况下,如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。

    def parse_one_page(html):
        pattern=re.compile('<dd>.*?board-index.*?>(d+)</i>.*?data-src="(.*?)".*?name">'
                          +'<a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">'
                          +'(.*?)</i>.*?fraction">(d+)</i>.*?</dd>',re.S)
        items=re.findall(pattern,html) ## 这个时候items是一个元组组成的列表
        for item in items:              ##遍历列表,用一个生成器来存储遍历到的结果
            yield {
                "index":item[0],
                 "title":item[2],
                 "actor":item[3].strip()[3:],
                 "time":item[4].strip()[5:],
                 "score":item[5]+item[6] ,
                 "image":item[1]
                
             }
        
    

     3.把爬取下来的结果存取下来。

       这里要用到 json.dumps()函数,需要注意的是json.dumps是将dict转化成str格式,json.loads是将str转化成dict格式.

      这儿我用的是with open函数来写的python 3中可以直接给open函数传入(encoding='utf-8')编码参数,但是python 2.7中需要引入codes模块才可以给open函数传入编码参数,否则会报错。

    def write_to_file(content):    
        with open('result.txt','a','utf-8') as f:
    #f=codecs.open('result.txt','a','utf-8') f.write(json.dumps(content,ensure_ascii=False)+' ')

     4.在猫眼Top100榜单看到,每个页面只展示了10个,网页通过一个偏移量offset来设置每个页面展示的上榜电影。

    url='http://maoyan.com/board/4?offset='+str(offset)
        html=get_one_page(url)
        for item in parse_one_page(html):
            write_to_file(item)
    

    5. 多线程爬取使用 multiprocessing 这个模块。

    5.整个代码块如下:

    # -*- coding: utf-8 -*-
    """
    Created on Thu Jun 29 10:23:46 2017
    
    @author: Tana
    """
    import requests
    import codecs
    import json
    from requests.exceptions import RequestException 
    import re
    import  multiprocessing 
    
    
    
    def get_one_page(url):
        try:
            response=requests.get(url)
            if response.status_code==200:
                response=response.text
                return response
            else:
                return None
        except RequestException:
            return None
            
    def parse_one_page(html):
        pattern=re.compile('<dd>.*?board-index.*?>(d+)</i>.*?data-src="(.*?)".*?name">'
                          +'<a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">'
                          +'(.*?)</i>.*?fraction">(d+)</i>.*?</dd>',re.S)
        items=re.findall(pattern,html)
        for item in items:
            yield {
                "index":item[0],
                 "title":item[2],
                 "actor":item[3].strip()[3:],
                 "time":item[4].strip()[5:],
                 "score":item[5]+item[6] ,
                 "image":item[1]
                
             }
        
      
    def write_to_file(content): 
        with codecs.open('result.txt','a','utf-8') as f:
            
            
       # f=codecs.open('result.txt','a','utf-8') 
            f.write(json.dumps(content,ensure_ascii=False)+'
    ')
            f.close()
      
    
    def main(offset):
        url='http://maoyan.com/board/4?offset='+str(offset)
        html=get_one_page(url)
        for item in parse_one_page(html):
            write_to_file(item)
        
       # print html
        
    if __name__=='__main__':
        pool=multiprocessing.Pool()
        pool.map(main,[i*10 for i in range(10)])
           


     

  • 相关阅读:
    全栈程工程师
    月薪8000的程序员和月薪2万的程序员差别在哪里?
    原型中的访问
    关于 基本类型和复合类型 用== 判断的小问题
    使用原型解决构造函数问题
    前端工程师学习路线 --书籍
    程序员成长之路
    GIT学习(1) Pull和Fetch
    OO面向对象编程:第四单元总结及课程总结
    OO面向对象编程:第三单元总结
  • 原文地址:https://www.cnblogs.com/yan-2010/p/7099759.html
Copyright © 2011-2022 走看看