通常,很多网站需要登录才能进行浏览,所以在爬取这些网站时,也需要进行登录,并拿取登录时的cookie
看到网站有篇文章《爬取邮政服务网点》使用了cookie爬网页,打算尝试一下。
我的环境是win10下的python2.7
step1.创建cookie.txt文件
获取cookie,并保存到cookie.txt(获取上海邮政网点)
# --coding:utf-8-- #
# cookie信息的加载与保存
import urllib
import urllib2
import cookielib
cookiejar = cookielib.MozillaCookieJar("cookie.txt")
cookiejar.load(ignore_discard=True)
handler = urllib2.HTTPCookieProcessor(cookiejar)
opener = urllib2.build_opener(handler)
resp = opener.open("http://iframe.chinapost.com.cn/jsp/type/institutionalsite/SiteSearchJT.jsp?community=ChinaPostJT&province=%E4%B8%8A%E6%B5%B7%E5%B8%82&pos=")
# ignore_discard=True 忽略被抛弃的东西(忽略过时的cookie信息)
cookiejar.save(ignore_discard=True)
for cookie in cookiejar:
print cookie
print "Cookie保存成功".decode('utf8').encode('gbk')
运行后,报错如下
cookielib.LoadError: 'cookie.txt' does not look like a Netscape format cookies file
查了网上攻略,原来需要在cookie.txt文件开头添加一句
# Netscape HTTP Cookie File
再次运行后,成功。
cookie.txt文件内容如下
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file! Do not edit.
iframe.chinapost.com.cn FALSE / FALSE JSESSIONID A8D7EE7FFF42C129AA3C3FAEFD1C5DF8
step2.利用cookie,获取邮政网点信息,这里我修改了原文的一些代码。
# -*- coding: utf-8 -*-
import requests
from lxml import etree
import pandas as pd
import cookielib
url='http://iframe.chinapost.com.cn/jsp/type/institutionalsite/SiteSearchJT.jsp?community=ChinaPostJT&province=%E4%B8%8A%E6%B5%B7%E5%B8%82&pos='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331',
'Referer': r'https://baike.baidu.com',
'Connection': 'keep-alive'
}
results=pd.DataFrame()
for i in range(2):
print i
#r=requests.get(url+str(i*10),headers=headers,cookies=cookie()).text
cookie = cookielib.MozillaCookieJar()
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
r=requests.get(url+str(i*10),headers=headers,cookies=cookie).text
comments=etree.HTML(r)
c1=comments.xpath('/html/body/table/tr/td[1]/text()')
c2=comments.xpath('/html/body/table/tr/td[2]/text()')
c3=comments.xpath('/html/body/table/tr/td[3]/text()')
c4=comments.xpath('/html/body/table/tr/td[4]/text()')
c5=comments.xpath('/html/body/table/tr/td[5]/text()')
c6=comments.xpath('/html/body/table/tr/td[6]/text()')
c7=comments.xpath('/html/body/table/tr/td[7]/text()')
result=pd.DataFrame([c1,c2,c3,c4,c5,c6,c7]).T
results = results.append(result)
results.to_excel('Result.xlsx',encoding='gbk')
运行后获得Result.xlsx,打开后结果如下。还需要清理一下数据。
注意:
py2中的Cookie相当于py3中的http.cookie
py2中的cookielib相当于py3的http.cookiejar
step3.数据清理
a.左边索引清除很容易。保存时候加一个参数index=False就行。
results.to_excel('Result.xlsx',encoding='gbk',index=False)
b.清除重复的【‘省’,‘市’,‘县’,‘服务网点名称’,‘邮编’,‘地址’,‘是否办理金融业务’】
这是原来网页上的表头,每个页上都有。
清除也很简单,把获得网页每列list的第一个忽略就可以。
result=pd.DataFrame([c1[1:],c2[1:],c3[1:],c4[1:],c5[1:],c6[1:],c7[1:]]).T
c.最后一个是修改列名
我原来打算在初始化时候加列名
colum = ['省','市','县','服务网点名称','邮编','地址','是否办理金融业务']
results=pd.DataFrame(columns=colum)
结果表头变成了上面这样,查了半天,也没有找到原因。
只好改成强行修改表头方式。
results.columns = ['省','市','县','服务网点名称','邮编','地址','是否办理金融业务']
results.to_excel('Result.xlsx',encoding='gbk',index=False)
注意:results中没有数据时候修改表头会报错。
最终代码
# -*- coding: utf-8 -*-
import requests
from lxml import etree
import pandas as pd
import cookielib
url='http://iframe.chinapost.com.cn/jsp/type/institutionalsite/SiteSearchJT.jsp?community=ChinaPostJT&province=%E4%B8%8A%E6%B5%B7%E5%B8%82&pos='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.3.2.17331',
'Referer': r'https://baike.baidu.com',
'Connection': 'keep-alive'
}
'''
def cookie():
with open('cookie.txt','r') as f:
cookies={}
for line in f.read().split(';'):
print line
name,value=line.strip().split('=',1)
cookies[name]=value
return cookies
'''
#colum = ['省','市','县','服务网点名称','邮编','地址','是否办理金融业务']
#results=pd.DataFrame(columns=colum)
results=pd.DataFrame()
for i in range(2):
#print i
cookie = cookielib.MozillaCookieJar()
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
r=requests.get(url+str(i*10),headers=headers,cookies=cookie).text
comments=etree.HTML(r)
c1=comments.xpath('/html/body/table/tr/td[1]/text()')
c2=comments.xpath('/html/body/table/tr/td[2]/text()')
c3=comments.xpath('/html/body/table/tr/td[3]/text()')
c4=comments.xpath('/html/body/table/tr/td[4]/text()')
c5=comments.xpath('/html/body/table/tr/td[5]/text()')
c6=comments.xpath('/html/body/table/tr/td[6]/text()')
c7=comments.xpath('/html/body/table/tr/td[7]/text()')
#result=pd.DataFrame([c1,c2,c3,c4,c5,c6,c7]).T
result=pd.DataFrame([c1[1:],c2[1:],c3[1:],c4[1:],c5[1:],c6[1:],c7[1:]]).T #把每个列表第一个数据忽略,因为是web的表头,不再需要
results = results.append(result)
results.columns = ['省','市','县','服务网点名称','邮编','地址','是否办理金融业务']
results.to_excel('Result.xlsx',encoding='gbk',index=False)
Result.xlsx内容如下,看上去正常了。
代码中还有可以改善的地方,就是循环条件,这个等空了再修改。