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

浙公网安备 33010602011771号