• 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)])
           


     

  • 相关阅读:
    hihocoder 1049 后序遍历
    hihocoder 1310 岛屿
    Leetcode 63. Unique Paths II
    Leetcode 62. Unique Paths
    Leetcode 70. Climbing Stairs
    poj 3544 Journey with Pigs
    Leetcode 338. Counting Bits
    Leetcode 136. Single Number
    Leetcode 342. Power of Four
    Leetcode 299. Bulls and Cows
  • 原文地址:https://www.cnblogs.com/yan-2010/p/7099759.html
Copyright © 2020-2023  润新知