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中,包含换行符\n,在这种情况下,如果不使用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)+'\n')

 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)+'\n')
        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)])
       

 

 


 

 

posted @ 2017-06-30 17:09  绵绵01  阅读(6111)  评论(0编辑  收藏  举报
levels of contents