Data acquisition and processing

Processing data in different formats

# 没有列名,可以手动加上去
pd.read_csv('data2.csv', names=['a', 'b', 'c', 'd', 'message'])
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo

# txt文件暴力读取
list(open('data3.txt'))
['            A         B         C\n', 
 'aaa -0.264438 -1.026059 -0.619500\n', 
 'bbb  0.927272  0.302904 -0.032399\n', 
 'ccc -0.264273 -0.386314 -0.217601\n', 
 'ddd -0.871858 -0.348382  1.100491\n']

result = pd.read_table('data3.txt', sep='\s+')	# '\s+'表示可能有若干个空格或制表
print(result)
            A         B         C
aaa -0.264438 -1.026059 -0.619500
bbb  0.927272  0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382  1.100491

# 跳过某些行
pd.read_csv('data4.csv', skiprows=[0, 2, 3])	#跳过第0,2,3行


# 把数据写入文本格式
data.to_csv('out.csv')

# 缺省值填充Null
data.to_csv(sys.stdout, na_rep='NULL')
,something,a,b,c,d,message
0,one,1,2,3.0,4,NULL
1,two,5,6,NULL,8,world
2,three,9,10,11.0,12,foo

# 手动读写数据(pandas吃内存)
import csv
f = open('data7.csv')
reader = csv.reader(f)
for line in reader:
    print(line)
['a', 'b', 'c']
['1', '2', '3']
['1', '2', '3', '4']

JSON formatted data

obj = \
"""
{"姓名": "张三",
 "住处": ["天朝", "挖煤国", "万恶的资本主义日不落帝国"],
 "宠物": null,
 "兄弟": [{"姓名": "李四", "年龄": 25, "宠物": "汪星人"},
              {"姓名": "王五", "年龄": 23, "宠物": "喵星人"}]
}
"""
import json
result = json.loads(obj)
{u'\u4f4f\u5904': [u'\u5929\u671d',
  u'\u6316\u7164\u56fd',
 u'\u4e07\u6076\u7684\u8d44\u672c\u4e3b\u4e49\u65e5\u4e0d\u843d\u5e1d\u56fd'],
 u'\u5144\u5f1f': [{u'\u59d3\u540d': u'\u674e\u56db',
   u'\u5ba0\u7269': u'\u6c6a\u661f\u4eba',
   u'\u5e74\u9f84': 25},
  {u'\u59d3\u540d': u'\u738b\u4e94',
   u'\u5ba0\u7269': u'\u55b5\u661f\u4eba',
   u'\u5e74\u9f84': 23}],
 u'\u59d3\u540d': u'\u5f20\u4e09',
 u'\u5ba0\u7269': None}

print json.dumps(result, encoding="UTF-8", ensure_ascii=False)
{"兄弟": [{"年龄": 25, "宠物": "汪星人", "姓名": "李四"}, {"年龄": 23, "宠物": "喵星人", "姓名": "王五"}], "住处": ["天朝", "挖煤国", "万恶的资本主义日不落帝国"], "宠物": null, "姓名": "张三"}

XML sum HTML

from lxml.html import parse
from urllib2 import urlopen

parsed = parse(urlopen('https://ask.julyedu.com/'))
doc = parsed.getroot()	# 获得根节点
links = doc.findall('.//a')	# 找到所有<a>节点
urls = [lnk.get('href') for lnk in doc.findall('.//a')]	# 得到其中'href'属性

# 解析XML
from lxml import objectify

path = 'Performance_MNR.xml'
parsed = objectify.parse(open(path))
root = parsed.getroot()

data = []

skip_fields = ['PARENT_SEQ', 'INDICATOR_SEQ',
               'DESIRED_CHANGE', 'DECIMAL_PLACES']

for elt in root.INDICATOR:	# 将XML放入pandas处理
    el_data = {}
    for child in elt.getchildren():
        if child.tag in skip_fields:
            continue
        el_data[child.tag] = child.pyval
    data.append(el_data)
perf = DataFrame(data)

Binary format

frame = pd.read_csv('data1.csv')
frame.to_pickle('frame_pickle')
pd.read_pickle('frame_pickle')
pickle:保持原来格式不动,以二进制形式输入

HDF5 format

store = pd.HDFStore('mydata.h5')
store['obj1'] = frame
store['obj1_col'] = frame['a']

Database-related actions

request and reptiles Technical Overview

The following code has been running outdated versions of some illogical

import requests

result = requests.get("http://news.qq.com/")
print(result.status_code)	# 200是正常的
result.encoding	#查看网页编码格式 GB2312
content = result.content
print(content[:1000])	# 网页前1000个字符
# BeautifulSoup库
import warnings
warnings.filterwarnings("ignore")

from bs4 import BeautifulSoup
soup = BeautifulSoup(content, from_encoding="GB2312") #注意这个地方
samples = soup.find_all("a", "linkto")
print(samples[0])
<a class="linkto" href="http://news.qq.com/a/20170421/002667.htm" target="_blank">\u5929\u821f\u4e00\u53f7\u53ef\u7528\u4e8e\u7a7a\u95f4\u7ad9\u8865\u7ed9 \u6fb3\u4e13\u5bb6\uff1a\u7f8e\u56fd\u90fd\u6ca1\u505a\u5230</a>
# 我们需要的是新闻的标题,因此直接取出sample的文本内容。我们通过sample.string完成这个操作。
print samples[0].string.encode('utf8')
# 如果我们需要把所有的标题都取出来,只需要对刚才的samples做一个解析就可以了。
for sample in samples:
    print sample.string
# 取出所有链接
for sample in samples:
    print sample.attrs['href']

Passing parameters in URLs

# 有时候我们需要在URL中传递参数,比如在采集百度搜索结果时,我们wd参数(搜索词)和rn参数(搜素结果数量),你可以手工组成URL
payload = {'wd': 'python', 'rn': '10'}
r = requests.get("http://www.baidu.com/s", params=payload)
print(r.url)

Set the timeout

# 通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误
requests.get('http://github.com', timeout=0.001)

Add Agent

# 爬虫爬取数据时为避免被封IP,经常会使用代理。requests也有相应的proxies属性
import requests

proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "http://10.10.1.10:1080",
}

requests.get("http://www.zhidaow.com", proxies=proxies)
# 如果代理需要账户和密码,则需这样
proxies = {
    "http": "http://user:[email protected]:3128/",
}

Request header content

r.request.headers

Simulated landing

s = requests.session()
data = {'user':'用户名','passdw':'密码'}
#post 换成登录的地址,
res=s.post('http://www.xxx.net/index.php?action=login',data);
#换成抓取的地址
s.get('http://www.xxx.net/archives/155/');

Reptiles crawl and analysis: chain of home network case

# 导入库
import requests
import time
from bs4 import BeautifulSoup

# 抓取列表页
# 首先了解一下目标网站URL结构
'''
链家网的二手房列表页面共有100个,URL结构为http://bj.lianjia.com/ershoufang/pg9/ 其中
bj表示城市
/ershoufang/是频道名称
pg9是页面码。
'''
'''
我们要抓取的是北京的二手房频道,所以前面的部分不会变,属于固定部分,
后面的页面码需要在1-100间变化,属于可变部分。将URL分为两部分,
前面的固定部分赋值给url,后面的可变部分使用for循环遍历页面
'''
#设置列表页URL的固定部分
url='http://bj.lianjia.com/ershoufang/'
#设置页面页的可变部分
page=('pg')

# 最好在http请求中设置一个头部信息,否则很容易被封ip。头部信息网上有很多现成的,也可以使用httpwatch等工具来查看
#设置请求头部信息
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept':'text/html;q=0.9,*/*;q=0.8',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding':'gzip',
'Connection':'close',
'Referer':'http://www.baidu.com/link?url=_andhfsjjjKRgEWkj7i9cFmYYGsisrnm2A-TN3XZDQXxvGsM9k9ZZSnikW2Yds4s&amp;amp;wd=&amp;amp;eqid=c3435a7d00146bd600000003582bfd1f'
}

# 使用for循环生成1-100的数字,转化格式后与前面的URL固定部分拼成要抓取的URL。这里我们设置每两个页面间隔0.5秒。抓取到的页面保存在html中
#循环抓取列表页信息
for i in range(1,101):
     if i == 1:
          i=str(i)
          a=(url+page+i+'/')
          r=requests.get(url=a,headers=headers)
          html=r.content
     else:
          i=str(i)
          a=(url+page+i+'/')
          r=requests.get(url=a,headers=headers)
          html2=r.content
          html = html + html2
     #每次间隔1秒
     time.sleep(1)


# 使用BeautifulSoup进行页面解析
#解析抓取的页面内容
lj=BeautifulSoup(html,'html.parser')

# 我们分别对房源的总价,房源信息和关注度三部分进行提取。 把页面div标签中class=totalPrice的部分提取出来,并使用for循环将其中每个房源的总价数据存在tp中。
#提取房源总价
price=lj.find_all('div','totalPrice')
tp=[]
for a in price:
    totalPrice=a.span.string
    tp.append(totalPrice)

# 房源信息存储在hi中,关注度存储在fi中
#提取房源信息
houseInfo=lj.find_all('div',attrs={'class':'houseInfo'})
 
hi=[]
for b in houseInfo:
    house=b.get_text()
    hi.append(house)

#提取房源关注度
followInfo=lj.find_all('div',attrs={'class':'followInfo'})
 
fi=[]
for c in followInfo:
    follow=c.get_text()
    fi.append(follow)


# 清洗数据并整理到数据表中
# 将之前爬取到的信息进行汇总,并导入pandas之中生成数据表。便于后面的分析
#导入pandas库
import pandas as pd

# 防止输出带省略号
pd.set_option('display.max_columns',200) #设置显示列数
pd.set_option('display.max_rows',100) #设置显示行数

#创建数据表
house=pd.DataFrame({'totalprice':tp,'houseinfo':hi,'followinfo':fi})
#查看数据表的内容
print(house.head())
  totalprice                                          houseinfo  \
0       1470  33| 144.35平米 || 精装 | 中楼层(10) | 2010年建 ...   
1        278   11| 51.91平米 || 简装 | 底层(10) | 2007年建 | 板楼   
2        345    21| 62平米 | 南 北 | 简装 | 低楼层(6) | 1985年建 | 板楼   
3        635  21| 84.77平米 || 精装 | 低楼层(21) | 2002年建 |...   
4        410  10| 38.54平米 | 西北 | 简装 | 中楼层(18) | 2005年建 ...   

         followinfo  
0  281人关注 / 2个月以前发布  
1  202人关注 / 2个月以前发布  
2   32人关注 / 1个月以前发布  
3  121人关注 / 3个月以前发布  
4    6人关注 / 1个月以前发布  

# 可以看到,很多信息是糊在一块的,不能直接使用,所以咱们再做一些数据提取和清洗的工作。如房源信息,在表中每个房源的户型,面积,朝向等信息都在一个字段中,无法直接使用。需要先进行分列操作。这里的规则比较明显,每个信息间都是以竖线分割的,因此我们只需要以竖线进行分列即可。

#对房源信息进行分列
houseinfo_split = pd.DataFrame((x.split('|') for x in house.houseinfo),index=house.index,columns=['户型','面积','朝向','装修','楼层','时间','结构'])

#查看分列结果
print(houseinfo_split.head())
      户型          面积     朝向    装修           楼层        时间     结构
0  33144.35平米      南    精装    中楼层(10)    2010年建      板楼
1  1151.91平米      北    简装     底层(10)    2007年建      板楼
2  2162平米    南 北    简装     低楼层(6)    1985年建      板楼
3  2184.77平米      南    精装    低楼层(21)    2002年建    板塔结合
4  1038.54平米     西北    简装    中楼层(18)    2005年建    板塔结合

#将分列结果拼接回原数据表
house=pd.merge(house,houseinfo_split,right_index=True, left_index=True)

# 使用相同的方法对房源关注度字段进行分列和拼接操作。这里的分列规则是斜杠
#对房源关注度进行分列
followinfo_split = pd.DataFrame((x.split('/') for x in house.followinfo),index=house.index,columns=['关注','发布时间'])
#将分列后的关注度信息拼接回原数据表
house=pd.merge(house,followinfo_split,right_index=True, left_index=True)

print(house.head())
         followinfo     户型          面积     朝向    装修           楼层        时间  \
0  281人关注 / 2个月以前发布  33144.35平米      南    精装    中楼层(10)    2010年建    
1  202人关注 / 2个月以前发布  1151.91平米      北    简装     底层(10)    2007年建    
2   32人关注 / 1个月以前发布  2162平米    南 北    简装     低楼层(6)    1985年建    
3  121人关注 / 3个月以前发布  2184.77平米      南    精装    低楼层(21)    2002年建    
4    6人关注 / 1个月以前发布  1038.54平米     西北    简装    中楼层(18)    2005年建    

      结构       关注      发布时间  
0     板楼  281人关注    2个月以前发布  
1     板楼  202人关注    2个月以前发布  
2     板楼   32人关注    1个月以前发布  
3   板塔结合  121人关注    3个月以前发布  
4   板塔结合    6人关注    1个月以前发布  

Published 21 original articles · won praise 5 · Views 1568

Guess you like

Origin blog.csdn.net/qq_36551226/article/details/104423856