python
这几天闲的无聊想做一个爬虫来爬取一些‘正经’网站,首先选择用python作为爬虫的语言。但是没有接触过python怎么办呢,只能从头开始学了。python学习地址这个是廖大神写的一个python入门,个人感觉写的非常不错,在粗略的学习了一遍之后感觉可以开始我的爬虫之旅了。
静态网页爬虫
目标:抓取http://tieba.baidu.com/p/2166231880中妹子的图片保存在本地
接下来分析一下我们需要做的事
- 获取网页html代码
- 将html中的图片地址提取出来
- 根据图片地址获取图片内容
- 将图片保存在本地
话不多少,直接上代码
from urllib import request
from html.parser import HTMLParser
import os
class MyHtml(HTMLParser):
path=os.path.join(os.path.abspath('.'),'pic')
if not os.path.exists(path):
os.mkdir(path)
def handle_starttag(self,tag,attrs):
if tag=='img' and attrs[0][0]=='pic_type' and attrs[0][1]=='0':
print(attrs[2][1])
with request.urlopen(attrs[2][1]) as picdate:
with open(os.path.join(self.path,attrs[2][1][-10:]),'wb') as fd:
fd.write(picdate.read())
with request.urlopen('http://tieba.baidu.com/p/2166231880') as f:
if f.status==200:
parser=MyHtml()
parser.feed(f.read().decode('utf-8'))
else:
print ('url error')
这一部分都比较简单,用urllib获取到页面信息后,通过HTMLParser对有用的信息进行提取,然后再使用urllib加载图片保存到本地
获取含有js的复杂网页
通过上一个例子我们已经对爬虫的爬取过程有了一个初步的了解,接下来我们需要接受更大的世界了。
目标:https://mm.taobao.com/search_tstar_model.htm?spm=719.1001036.1998606017.2.pA4hNo
首先想到的是通过之前的经验,先获取html再从html中加载图片信息。
但是通过查看网页的源码后就发现,原来网页上的那么多的妹子的图片居然一张也没有在源码中显示。看来原来爬取静态网页的方法已经不适用了,我们要使用其他的手段了。
分析出现上述结果是因为网页上的图片项都是通过js添加进去的,那么我们有两种方法来解决这个问题:
- 分析js代码,找出添加的内容
- 先让js运行,我们从js处理完毕的html中获取我们想要的信息
这里我们选择第二种方法,为了让js运行就需要一些工具
selenium+PhantomJS
selenium是一个自动化测试工具,可以同过 pip install selenium 来安装
PhantomJS其实就是一个浏览器,只是它没有界面,我们的js就是依赖它来执行的。http://phantomjs.org/download.html从这个地址下载,把其中的phantomjs.exe文件放在python目录下(确保你的python目录已经在环境变量中配置好了)
还有一个非常实用的爬虫工具需要安装pip install beautifulsoup4,这个是用来提取html元素的。如果不是很了解可以参考这篇文章
好了,准备工作都做好了,可以开工了
from urllib import request
from bs4 import BeautifulSoup
from selenium import webdriver
import os
import time
class MyHtml():
def __init__(self):
self.host='https://mm.taobao.com/search_tstar_model.htm?spm=719.1001036.1998606017.2.pA4hNo'
self.path=os.path.join(os.path.abspath('.'),'mm')
if not os.path.exists(self.path):
os.mkdir(self.path)
self.browser=webdriver.PhantomJS()
self.count=0
def start(self,n=False):
if not n:
print(self.host)
self.browser.get(self.host)
print('第'+str(self.count)+'项')
self.soup=BeautifulSoup(self.browser.page_source)
for li in self.soup.find_all('li',class_='item'):
self.img=li.find('img')
if self.img.has_attr('data-ks-lazyload'):
self.src='https:'+self.img['data-ks-lazyload']
else:
self.src='https:'+self.img['src']
print(self.src)
self.name=str(li.find('span',class_='name').string)
try:
with request.urlopen(self.src) as pic:
if pic.status==200:
with open(os.path.join(self.path,self.name+'.jpg'),'wb') as pici:
pici.write(pic.read())
except BaseException:
print('这个地址有问题')
if self.count<10:#数据太多这里只取前十项
self.browser.find_element_by_class_name('page-next').click()
# time.sleep(3)
self.start(True)
self.count=self.count+1
if '__main__'==__name__:
MyHtml().start()
最后
到这里我们已经知道了python爬虫的入门用法。但是我们发现这个爬虫的效率太低,这时可以用多线程提高爬虫效率。当同一个ip在一个网站访问频率太高时可能会出现验证码,这时需要做访问延迟和使用代理ip。爬虫路还很长,还有许多知识需要学习。