python之路[25] - 爬虫

传统方式是使用requests请求接口,然后用HTMLParser解析网页,使用scrapy框架可以快速的爬取页面内容

请求流程

1 访问首页后就能获取cookies,然后通过这个cookies再请求登录接口,
2 服务器记录这个cookies标记为已登录状态,
3 比较坑的是,有可能会产生很多cookies有些是站长助手创建的,这个问题困扰我很久,完全可以忽视. 当然也有可能是反爬的功能

 

import sys
reload(sys)
sys.setdefaultencoding('utf-8')   #有些网页是中文的,所以必须加个默认字符集,不然会有错误

def queryData():
    r = requestPost(
        url = "http://hzcs.qsng.cn/hz-bsp/hz/apply-front.action",
        headers = {
                "Content-Type" : 'application/json',
                "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
                }
        )

    cookies = r.cookies['JSESSIONID']  # 获取cookie

    r = requestPost(
        url = "http://hzcs.qsng.cn/hz-bsp/hz/login-front!login.action",  # 登录接口
        data = {"username":"tt", 
                "password":"yy",
                "memberId":"",
                "area":0},
        cookies={"JSESSIONID":cookies},
        headers={
                "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
                "Host":"hzcs.qsng.cn",
                "Origin":"http://hzcs.qsng.cn",
                "Referer":"http://hzcs.qsng.cn/hz-bsp/hz/apply-front.action",
                "Upgrade-Insecure-Requests": "1",
                "Content-Length": "65",
                "Content-Type" : 'application/x-www-form-urlencoded',
                },
        )

    r = requestPost(
        url = "http://hzcs.qsng.cn/hz-bsp/hz/apply-front!list.action", # 获取列表接口
        data = {"query":"", 
                "area":5, 
                "term":0,
                "spelld":"",
                "weekDay":"",
                "beginHour":"",
                "beginMini":"",
                "endHour":"",
                "endMini":"",
                },
        cookies={"JSESSIONID":cookies},
        headers={
                "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
                "Host":"hzcs.qsng.cn",
                "Origin":"http://hzcs.qsng.cn",
                "Referer":"http://hzcs.qsng.cn/hz-bsp/hz/apply-front.action",
                "Upgrade-Insecure-Requests": "1",
                "Content-Length": "65",
                "Content-Type" : 'application/x-www-form-urlencoded',
                },
        )

    return r

  

HTMLParser

获取到原始页面后,这个网页是需要爬下来的页面: 首页|专业|班级名|总费用|区域|班级状态|报名

<table width="100%" border="0" cellspacing="1" cellpadding="0" class="tb">
<tr>
  <td width="8%" align="center" bgcolor="#c8e0bf">专业</td>
  <td width="8%" align="center" bgcolor="#c8e0bf">班级名</td>
  <td width="28%" bgcolor="#c8e0bf">班级信息</td>
  <td width="10%" align="center" bgcolor="#c8e0bf">总费用</td>
  <td width="9%" align="center" bgcolor="#c8e0bf">区域</td>
                                  <td width="10%" align="center" bgcolor="#c8e0bf">班级状态</td>
  <td width="10%" align="center" bgcolor="#c8e0bf">报名</td>
</tr>
<tr>
    <td align="center" bgcolor="#FFFFFF">绘画涂鸦亲子</td>
    <td align="center" bgcolor="#FFFFFF"><a href="apply-front!clazzView.action?clazzId=549DB75B36CC4007BB19C07F39D8BC5F&area=5" class="r12"/>B1D08-1</a></td>
    <td bgcolor="#FFFFFF">年级或年龄要求:                                                          
      <br>学员出生介于:2015-03-01  ~   2015-08-31</br>性别要求: 不限  程度:启蒙课次:15<br/>
        学期:春季2019-02-24开班<br/>
        上课时间、地点:<pre>周日 08:30-09:30 滨江分中心303</pre>班级类型: 普通班级招生性质: 招新生 <br/>
        (<a href="apply-front!clazzView.action?clazzId=549DB75B36CC4007BB19C07F39D8BC5F&area=5" class="r12">点击查看详情</a>)
    </td>
    <td align="center" bgcolor="#FFFFFF">900.0</td>
    <td align="center" bgcolor="#FFFFFF"><font color="red">滨江分中心</font></td>
    <td align="center" bgcolor="#FFFFFF">名额已满</td>
    <td align="center" bgcolor="#FFFFFF">
      <a href="apply-front!netApply.action?clazzId=549DB75B36CC4007BB19C07F39D8BC5F&area=5" />
      <font color="red">点击报名</font></a>
      <br/>
    </td>
</tr>

  

class MyHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)  # 初始化一个父类,注意HTMLParser是经典类
        self.items = []
        self.content = []
        self.in_td = False

    def _get_attr(self,attrs,attrname):  # 定义一个解析属性函数,html标签中的属性和属性值在htmlparser解析器中是个tuple类型,返回属性名对应的属性值
        for attr in attrs:
            if attr[0] == attrname:
                return attr[1]
        return None

    def handle_starttag(self, tag, attrs):   # 重写handle_starttag函数,该函数在查找到标签头自动调用,attrs包含该标签tag中所有的属性和属性值,类型是个列表,其中的元素都是tuple类型(属性名,属性值)
        if tag == 'td' and self._get_attr(attrs,'align') == "center":
            self.in_td = True
            
    def handle_endtag(self, tag):  # 重写handle_endtag函数,该函数在查找到标签
        if tag == 'td' and self.in_td:
            self.in_td = False

    def handle_data(self, data):   # 重写handle_data函数,该函数在查找到标签中的内容自动调用,利用正则表达式进行了匹配,如果匹配成功,匹配出来的再做文本处理
        if self.in_td :
            data = data.replace("\r\n","").replace(" ","").replace("\t","")
            if len(data)>0:
                if data.find(u"报名".encode('utf-8'))>-1:
                    self.content.append(data)
                    item = "|".join(self.content)
                    self.items.append(item)
                    self.content = []
                else:
                    self.content.append(data)

  

 

 

 爬虫框架scrapy

 

import codecs
from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapy.http import Request,FormRequest


class mySpider(Spider):
    name = "hzcs"
    allowed_domains = "hzcs.qsng.cn"
    header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
              'Referer':"http://hzcs.qsng.cn/",
                }  #设置浏览器用户代理

    def start_requests(self):
        """第一次请求一下登录页面,设置开启cookie使其得到cookie,设置回调函数"""
        return [Request('http://hzcs.qsng.cn/hz-bsp/hz/apply-front.action',headers=self.header,meta={'cookiejar':1},callback=self.parse)]

    def parse(self, response):
        # 响应Cookies
        Cookie1 = response.headers.getlist('Set-Cookie')                            #查看一下响应Cookie,也就是第一次访问注册页面时后台写入浏览器的Cookie
        print('response Cookies:',Cookie1)

        data = {"username":"33010820150505093X", 
                "password":"15305713256",
                "memberId":"",
                "area":0}
        print "login...."
        return [ FormRequest.from_response(response,
                                         url="http://hzcs.qsng.cn/hz-bsp/hz/login-front!login.action",
                                         meta={"cookiejar":response.meta['cookiejar']},
                                         headers=self.header,
                                         formdata=data,
                                         callback=self.next,
                                         )]

    def next(self,response):
        Cookie2 = response.requests.headers.getlist('Set-Cookie')
        print("response Cookies2:", Cookie2)
        yield Request('http://hzcs.qsng.cn/hz-bsp/hz/apply-front!list.action',meta={'cookiejar':True},callback=self.next2)


    def next2(self,response):
            # 请求Cookie
            Cookie3 = response.request.headers.getlist('Cookie')
            print('查看需要登录才可以访问的页面携带Cookies:',Cookie3)

            leir = response.xpath('//div[@class="tu"]/a/text()').extract()  #得到个人中心页面
            print('最终内容',leir)
            leir2 = response.xpath('//div[@class="set-tags"]/a/text()').extract()  # 得到个人中心页面
            print(leir2)

  

单次执行
    scrapy runspider scrapy_test.py

  

 

posted @ 2019-01-05 15:02  richardzgt  阅读(269)  评论(0编辑  收藏  举报