登录/注册 搜索
首页 / SEO基础 / Python学习笔记-爬虫(1)通过案例梳理简单爬虫的基础知识点
返回

Python学习笔记-爬虫(1)通过案例梳理简单爬虫的基础知识点

浏览次数:54 分类:SEO基础

写作背景:作为一名金融从业者,在个人的业务投资上,经常会需要通过数据分析,加上金融逻辑的推演决定自己的投资策略。提到数据分析,就必然会提到数据采集。作为个人投资者,数据信息最多的就是来自互联网。如何高效获取自己需要的数据并加以分析,就是在下开始学习爬虫的原因。通过记录学习情况,梳理自己的知识框架,同时也能分享给大家,找到一起努力奋斗的小伙伴。

个人背景:理工科类大学毕业,从事银行、保险等金融相关工作近10年。

编程能力:大学期间学过C语言和SQL语言,但是10年来几乎很少应用,忘得差不多。

学习Python的原因:网上关于Python的爬虫案例较多,据说Python语言相比C和JAVA更近自然语言。

学习时长:工作之后的业余时间,累计近一个月。

学习成果:掌握简单的爬虫技术。

系统环境:windows 10

IDE:Pycharm

Python版本:Python2.7 (Ananconda)

知识点:1、涉及到的库urllib,urllib2,re,beautifulsoup,lxml,gzip,StringIO,csv,mysql

2、掌握用urllib,urllib2获取网页

1)最简单的获取方式urllib2.urlopen()

2)加入报头headers

3)加入代理proxy

4)加入cookies

5)定制自己的opener

6)网页乱码的处理:chardet、decode()、gzip、StringIO库

3、通过网页解析,获得需要的数据

1)学会用正则表达式解析

2)学会用BeautifulSoup解析网页

3)学会用lxml xpath解析网页

4、数据的读写

1)txt文件的读写

2)CSV文件的读写

3)MySQL的读写

本文适用人群:零基础学爬虫、小白学爬虫、简单爬虫的学习框架

其他:1)本文通过爬虫案例学习以上学习以上知识点。并尽可能对每一段代码做注解,

注解开头为#。

2)本文不会涉及到class类和函数的概念,便于初学者学习基本知识。

3)本文仅作为知识学习的笔记与分享,请勿在未经作者的同意下商用seo爬虫基础知识,更希望每一个编程爱好者以阳光的心态学习,不要用于违法乱纪。

参考网站:1)廖雪峰的Python 2.7教程:学习所有Python的最基础语法,当词典用。

2)简明 Python 教程,当词典用

3)崔庆才的个人博客,Python爬虫学习系列教程 | 静觅,相当多的实例教程,唯一 缺点就是很多文章是半年前到1年前写的,很多网页都纷纷改版,直接运行里 面的代码无法爬取,但是可以作为爬虫思路的指引。

爬取对象:上海房产网_上海二手房_上海新房_上海租房-上海链家网

感谢链家网,提供了很好的学习土壤。

我是分割线————————————————————————————————————

正文与代码:

<code class="language-python"># encoding: utf-8

#该行注释是为了解决python中文的乱码问题,所有中文以utf-8格式解析,也可以写成 # -*- coding: utf-8 -*-

1、添加需要用到的库urllib,urllib2,re,beautifulsoup,lxml,csv,mysql,gzip,StringIO

import urllib #网页解析库
import urllib2 #网页解析库
import re  # 正则表达式的库
import cookielib  #cookie的库
from bs4 import BeautifulSoup  # BeautifulSoup的库
import lxml.html  # lxml xpath的库
from lxml import etree # lxml xpath的库
import csv #csv的库
from mysql import connector  # 连接MySQL的库

库的安装命令,cmd下执行:pip install urllib

pip install urllib==1.0.0 #制定版本的库安装

pip install –upgrade urllib #库的升级

其他pip命令可以参考:pip安装使用详解 – 爱开源

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

2、掌握用urllib,urllib2获取网页

1)最简单的形式:

url = 'http://sh.lianjia.com/ershoufang/d1'
response = urllib2.urlopen(url)
content = response.read()
print content

输出结果:

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

说明爬取成功,看来链家非常的友好,并没有设立针对urlopen显性的反爬虫机制。

怎么判断爬取是否成功

print content.getcode()

如果返回值是200则爬取成功,如果是301、302则是重定位,如果是404则是表示页面不存在

详细可以参考 301、404、200、304等HTTP状态 – Lynn.Zhou的专栏 – 博客频道 – CSDN.NET

2)加入报头headers,如果遇到有显性反爬虫机制的情况,返回一般就不是200了,这个时候怎么办?就给爬虫带个帽子,假装自己不是爬虫。

headers = {
    'User - Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}

报头一般用浏览器按F12,查看Network选项卡里都能看到,实在不行,你可以把整个Request Headers里的内容,以字典的方式扔进去。

python网络爬虫基础_seo爬虫基础知识_seo新手基础入门seo秘籍

3)尝试加入代理IP机制,现在越来越多的网站 没有显性的反爬虫模式,而是采用隐性的反爬虫机制,比如你开始爬取第一页的时候没问题,但是爬着爬着就把你BAN了,而一般BAN的是你的IP地址,所以在做大量数据爬取的时候建议加入IP代理机制。

代理IP地址怎么获取,请自行百度或者谷歌。

proxy_handler = urllib2.ProxyHandler({"http": '101.231.67.202:808'})
opener = urllib2.build_opener(proxy_handler,urllib2.HTTPHandler)

4)加入cookies

cookie = cookielib.LWPCookieJar()
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(cookie_handler,urllib2.HTTPHandler)

5)定制自己的opener

#同时加入proxy和cookie
opener = urllib2.build_opener(proxy_handler,cookie_handler,urllib2.HTTPHandler)

6)网页乱码的处理:chardet、decode()、gzip、StringIO 乱码表现一:chardet、decode()

python网络爬虫基础_seo爬虫基础知识_seo新手基础入门seo秘籍

seo爬虫基础知识_python网络爬虫基础_seo新手基础入门seo秘籍

有时解析网页会发现大量的奇怪符号,嗯,这就是乱码。乱码的一般都是中文。

访问的网站是搜狐,同样调取查看器。

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

在里有以下内容:

说明网站的中文是用GBK的。

print content.read().decode('gbk')

python网络爬虫基础_seo爬虫基础知识_seo新手基础入门seo秘籍

decode的其他形式:decode('utf-8','ignore') #忽略不能解码的内容,确保命令正常运行

用chardet的库来解析网络的代码

import chardet
url = 'http://www.sohu.com'
response = urllib2.urlopen(url)
content = response.read()
charset_info = chardet.detect(content)
print charset_info

乱码表现二:调用gzip、StringIO库

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

所有的内容都乱码了。。。。

明明是gb2312,用decode('gbk','ignore')居然不能解码。。。

乱码的网页报头

python网络爬虫基础_seo爬虫基础知识_seo新手基础入门seo秘籍

普通网页的报头

seo爬虫基础知识_seo新手基础入门seo秘籍_python网络爬虫基础

关键在于RESPONSE里是否有 Vary:Accept-Encoding。如果没有申明,网页要自行解压。

gzip和StringIO派上用处了:

import gzip
import StringIO
url = 'http://land.fang.com'
response = urllib2.urlopen(url)
content = response.read()
content = StringIO.StringIO(content)
gzipper = gzip.GzipFile(fileobj=content)
content = gzipper.read().decode('gbk')

seo新手基础入门seo秘籍_python网络爬虫基础_seo爬虫基础知识

3、通过网页解析,获得需要的数据

还是以上海二手房|上海二手房出售|最新上海二手房信息 – 上海链家网为案例

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

获取所有行政区的链接和名字

1)学会用正则表达式解析

pattern_district = re.compile('(.*?)', re.S)
districts = re.findall(pattern_district, content)
for district in districts:
     print district

熟练掌握.*?和(.*?)的贪婪匹配技巧seo爬虫基础知识,一般都能轻松获取

但是如果要获取行政区的链接就很痛苦了,因为正则表达式只能找规律,周围匹配的字段越特殊,那么越容易找到。

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

pattern_district = re.compile('(.*?)', re.S) 
districts = re.findall(pattern_district, content)
for district in districts: 
print district 

这样写的结果,会匹配到很多不想管的内容

seo新手基础入门seo秘籍_python网络爬虫基础_seo爬虫基础知识

打包一起找再处理

pattern_district = re.compile('<a href="/ershoufang/".*?.*?
(.*?)
'
,re.S) districts = re.findall(pattern_district, content) districts =districts[0] print districts

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

再一次正则匹配:

pattern = re.compile('(.*?)',re.S)
item = re.findall(pattern,districts)
for i in item:
    print i[0], i[1]

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

是不是有种抠图的快感,哈哈。

2)学会用BeautifulSoup解析网页

from bs4 import BeautifulSoup
print type(content)
soup = BeautifulSoup(content,'lxml')
print type(soup.prettify())

#搜索行政区域
items = soup.find('div',class_="option-list gio_district").find_all('a',class_="")
# print items
for item in items:
    district = item.get_text()
    district_url = item.get('href')
    print district,district_ur

seo爬虫基础知识_seo新手基础入门seo秘籍_python网络爬虫基础

find()找到第一个匹配的内容就返回,find_all找到所有匹配的内容,get_text()获取标签内的文本内容,get('href')获取标签内的属性值。

用BeautifulSoup的感觉是不是逻辑很清晰?类似人类语言?

3)学会用lxml xpath解析网页

from lxml import etree
tree = lxml.html.fromstring(content)
html = lxml.html.tostring(tree,pretty_print=True)

或者

from lxml import etree
tree = etree.HTML(content)
html = etree.tostring(html)

#获取行政区列表

results = tree.xpath('//div[@class="option-list gio_district"]/div[@class="item-list"]/a')
for district in results:
print district.text

#获取行政区链接

district_url = tree.xpath('//div[@class="option-list gio_district"]/div[@class="item-list"]/a/@href')
for district_url in district_url:
    print 'http://sh.lianjia.com/ershoufang'+district_url

seo新手基础入门seo秘籍_python网络爬虫基础_seo爬虫基础知识

lxml xpath的逻辑也很清晰。

获取每一个房子的内容信息:

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

都在的标签下

难点:需要获取的内容不在标准的标签内。

seo爬虫基础知识_python网络爬虫基础_seo新手基础入门seo秘籍

1)学会用正则表达式解析

# 对象是content,用正则表达式去匹配房子信息:下层链接,小区,户型,面积,楼层、朝向、建造时间,描述1,描述2,描述3,总价,单价,查看人数
# 无法匹配到| 下 楼层、朝向、建造时间的内容
pattern = re.compile('
.*?

.*?<a name.*? href="(.*?)" title' '.*?
.*?(.*?)' '  .*?(.*?)  ' '.*?(.*?)  ' # '.*?
.*?<a href=.*?| (.*?)
.*?
' '.*?
.*?<a href=.*?(.*?)
.*?
' # '.*?
.*?<a href=.*?|(*?)
' '.*?(.*?)' '.*?(.*?)' '.*?(.*?)' '.*?(.*?)' '.*?
(.*?)
'
'.*?(.*?)' , re.S) items = re.findall(pattern, content) # print items new_item = [] for item in items: # print item[5],item[6],item[7],item[8],item[9],item[10] # print item[0],item[1],item[2],item[3],item[4] #g给子项链接补完 new_item0 = "http://sh.lianjia.com" + item[0] #难点ch,楼层、朝向和建造时间需要再处理提取 new_item4 = item[4].strip() new_item4 = new_item4.replace('n','') # new_item4 = new_item4.replace(' ','') new_item4 = new_item4.replace('t', '') new_item4 = new_item4.split('| ') #建造时间不是每一项都有,对于没有的要补完 if len(new_item4)<3: new_item4.append(' ') # print new_item4 #创建新的字段 new_item.append([new_item0,item[1],item[2],item[3],new_item4[0],new_item4[1],new_item4[2],item[5],item[6],item[7],item[8],item[9],item[10]]) for i in new_item: print i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[8],i[9],i[10],i[11],i[12]

seo爬虫基础知识_seo新手基础入门seo秘籍_python网络爬虫基础

2)学会用BeautifulSoup解析网页

soup = BeautifulSoup(content,'lxml')
# print soup.prettify()
#对象为soup
# 获取房子信息:下层链接,标题,小区,户型,面积,楼层、朝向、建造时间,距离,满五,钥匙,总价,单价,查看人数
items2 = soup.find('ul',id="house-lst").find_all('li')
# print items2
datas = []
for item in items2:
    #子链接
    url = item.find('h2').a.get('href')
    url = "http://sh.lianjia.com"+url
    #标题
    title = item.find('h2').a.get_text()
    #小区

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

block = item.find('div',class_='col-1').a.get_text() #户型 type = item.find('div',class_='where').find_all('span')[1].get_text() #面积 area = item.find('div',class_='where').find_all('span')[2].get_text() #楼层、朝向、建造时间比较难获取 text = item.find('div',class_='con').get_text() text = text.replace("n","").replace("t","").replace(" ","").split("|") #楼层 floor =text[1] #朝向 orientation = text[2] #建造时间 if len(text) ==4: buildtime = text[3] else: buildtime = " " #距离 if item.find('span',class_="fang-subway-ex"): distance = item.find('span',class_="fang-subway-ex").span.get_text() else: distance = " " #满五免税 tax = item.find('span',class_="taxfree-ex").span.get_text() #钥匙 key = item.find('span',class_='haskey-ex').span.get_text() #总价 price = item.find('span',class_="num").get_text() #单价 price_pre = item.find('div',class_="price-pre").get_text() #查看人数 num_look = item.find('div',class_='square').span.get_text() print url,title,block,type,area,floor,orientation,buildtime,distance,tax,key,price,price_pre,num_look datas.append([url,title,block,type,area,floor,orientation,buildtime,distance,tax,key,price,price_pre,num_look]) #子链接,标题,小区,户型,面积,楼层、朝向、建造时间,距离,满五,钥匙,总价,单价,查看人数

seo新手基础入门seo秘籍_seo爬虫基础知识_python网络爬虫基础

3)学会用lxml xpath解析网页

tree = lxml.html.fromstring(content)
html = lxml.html.tostring(tree,pretty_print=True)
#获取房子信息:下层链接,标题,小区,户型,面积,楼层、朝向、建造时间,距离,满五,钥匙,总价,单价,查看人数
#下层链接
urls = tree.xpath('//li/div[@class="info-panel"]/h2/a/@href')
print len(urls)
# for url in urls:
#     print 'http://sh.lianjia.com'+url
#标题
titles = tree.xpath('//li/div[@class="info-panel"]/h2/a')
# for title in titles:
#     print title.text
#小区
blocks = tree.xpath('//li/div[@class="info-panel"]/div[@class="col-1"]/div/a/span')
# for block in blocks:
#     print block.text
#户型
types = tree.xpath('//li/div[@class="info-panel"]/div[@class="col-1"]/div/span[1]')
# for type in types:
#     print type.text
#面积
areas = tree.xpath('//li/div[@class="info-panel"]/div[@class="col-1"]/div[@class="where"]/span[2]')
# for area in areas:
#     print area.text
#难点,楼层、朝向、建造年代的内容居然再标签外
texts = tree.xpath('//li/div[@class="info-panel"]/div[@class="col-1"]/div[@class="other"]/div[@class="con"]')
# print texts
#楼层
floors = []
#朝向
orientations = []
#建造时间

seo新手基础入门seo秘籍_python网络爬虫基础_seo爬虫基础知识

buildtimes = [] for text in texts: text = text.xpath('string(.)') text = text.replace("n","").replace(" ","").replace("t","").split("|") floors.append(text[1]) orientations.append(text[2]) if len(text)==4: buildtimes.append(text[3]) else: buildtimes.append(" ") # for floor in floors: # print floor # # for orientation in orientations: # print orientation # # for buildtime in buildtimes: # print buildtime #距离 distances = tree.xpath('//span[@class="fang-subway-ex"]/span') for distance in distances: print distance.text #满五 taxes = tree.xpath('//span[@class="taxfree-ex"]/span') # for tax in taxes: # print tax.text #钥匙 keys = tree.xpath('//span[@class="haskey-ex"]/span') # for key in keys: # print key.text #总价 prices = tree.xpath('//span[@class="num"]') # for price in prices: # print price.text #单价 prices_pre = tree.xpath('//div[@class="price-pre"]') # for price_pre in prices_pre: # print price_pre.text #查看人数 nums = tree.xpath('//div[@class="square"]/div/span[@class="num"]') # for num in nums: # print num.text #获取房子信息:下层链接,标题,小区,户型,面积,楼层、朝向、建造时间,距离,满五,钥匙,总价,单价,查看人数 datas = [] i = 0 while i <len(urls): url = "http://sh.lianjia.com"+urls[i] title = titles[i].text block = blocks[i].text type = types[i].text area = areas[i].text floor = floors[i] orientation = orientations[i] buildtime = buildtimes[i] distance = distances[i].text tax = taxes[i].text key = keys[i].text price = prices[i].text price_pre =prices_pre[i].text num = nums[i].text datas.append([url,title,block,type,area,floor,orientation,buildtime,distance,tax,key,price,price_pre,num]) i += 1 for data in datas: print data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10],data[11],data[12],data[13]

seo爬虫基础知识_python网络爬虫基础_seo新手基础入门seo秘籍

4、数据的读写

函数:open('文件名‘,'参数’)

参数:w,wb,r,rb,a,ab

详细参考:Python文件I/O – Python教程 1)txt文件的读写

函数:write(‘数据’)

#存储到TXT
#建立文件
#设置文件名
title = "sh_lianjia_ershoufang"
#打开要写的文件,没有的话创建,参数w表示重新写入

file = open(title+".txt","w")
#开始写入文件
for data in datas:
# data = data.encode('utf-8')
    file_data = []
for item in data:
        item = item.strip().encode('utf-8')
#不能写入列表,只能一个一个写入,默认空格区分
        file.write(item+",")
    file.write("n")
# print file_data
    # file.write(file_data)
print title+" is writed"
#txt的内容读取
file = open("sh_lianjia_ershoufang.txt","r")
f = file.readlines()
print f
for i in f:
print i
file.close()

python网络爬虫基础_seo新手基础入门seo秘籍_seo爬虫基础知识

2)CSV文件的读写

csvfile = file('csv_sh_lj_2s.csv','ab')
writer = csv.writer(csvfile)
for data in datas:
    csv_data = []
    for item in data:
        item = item.strip().encode('utf-8')
        csv_data.append(item)
    writer.writerow(csv_data)
csvfile.close()
print "csv_sh_lj_2s.csv has been saved."
#csv的读取
csvfile_read = file('csv_sh_lj_2s.csv','rb')
reader = csv.reader(csvfile_read)
for line in reader:
    print line
csvfile_read.close()

open(title,wb)的输出结果:

seo爬虫基础知识_seo新手基础入门seo秘籍_python网络爬虫基础

open(title.'w')的输出结果

seo新手基础入门seo秘籍_python网络爬虫基础_seo爬虫基础知识

3)MySQL的读写

#创建链接
params = dict(host='localhost',port = 3306 ,user ='root',password = 'root', database='test')
conn = connector.connect(**params)
#创建指标
cursor= conn.cursor()
#创建表:下层链接,标题,小区,户型,面积,楼层、朝向、建造时间,距离,满五,钥匙,总价,单价,查看人数
ddl = """
    create table lianjia_sh(id integer, url varchar(100), title varchar(100), block varchar(100), type varchar(100), area varchar(100), floor varchar(100), orientation varchar(100), buildtime varchar(100), distance varchar(100), tax varchar(100), have_key varchar(100), price varchar(100), price_pre varchar(100), num varchar(100))
"""
#插入内容:
sqltext = """
    insert into lianjia_sh(url,title,block,type,area,floor,orientation,buildtime,distance,tax,have_key,price,price_pre,num) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
"""
# for data in datas:
#     cursor.execute(sqltext,data)
#     conn.commit()
# data_eg = ['/ershoufang/sh4281292.html','温馨之家,业主诚意出售,链家推荐,好房待售','梅陇二村','45.01平 ','中区/6层','朝南','1988年建','距离1号线莲花路站832米','满五','有钥匙','240','53321元/平','85']
cursor.executemany(sqltext,datas)
#指针提交,不然回滚
conn.commit()
conn.close

python网络爬虫基础_seo爬虫基础知识_seo新手基础入门seo秘籍

本文作为学习笔记,会不定期更新。

后续学习内容:

解决反爬虫机制

如何设立代理池

如果模拟登陆

本文很早就写好了,但是居然一直忘记发布,原来一直在草稿箱里。。。。。算了 就给自己当笔记用吧

您好!请登录

点击取消回复

    购物车

    X

    我的足迹

    X
    FUNION飞优免费测评网站质量:
    定制方案
    x

    力荐定制全网营销型网站已有10967548位客户定制营销型网站方案

    网站类型*
    建站目的*
    建站周期*
    行业类型*
    公司名称* 姓名* 手机号码*
    适合您的网站类型 ? 建站类型 ? 建站目的 ? 建站要求? 建站预算? 预期周期? 交付周期?
    我要定制

    飞优

    网站建设 | SEO优化 | SEM托管 | 信息流推广 | 口碑营销

    姓名
    邮箱
    手机
    留 言: