python爬虫 入门+进阶_Python爬虫入门与进阶

爬虫是在没有(用)API获取数据的情况下以Hack的方式获取数据的一种有效手段;进阶,就是从爬取简单页面逐渐过渡到复杂页面的过程。针对特定需求,爬取的网站类型不同,可以使用不同的python库相结合,达到快速抓取数据的目的。但是无论使用什么库,第一步分析目标网页的页面元素发现抓取规律总是必不可少的:有些爬虫是通过访问固定url前缀拼接不同的后缀进行循环抓取,有些是通过一个起始url作为种子url继而获取更多的目标url递归抓取;有些网页是静态数据可以直接获取,有些网页是js渲染数据需要构造二次请求……如果统统都写下来,一篇文章是不够的,这里举几个典型的栗子:

以从OPENISBN网站抓取图书分类信息为例,我有一批图书需要入库,但是图书信息不全,比如缺少图书分类,此时需要去openisbn.com网站根据ISBN号获取图书的分类信息。如《失控》这本书, ISBN: 7513300712 ,对应url为 http://openisbn.com/isbn/7513300712/,分析url规律就是以http://openisbn.com/isbn/作为固定前缀然后拼接ISBN号得到;然后分析页面元素作为固定前缀然后拼接ISBN号得到;然后分析页面元素,Chrome右键 —> 检查:直接使用urllib2 + re 来获得“Category:” 信息:import re

import urllib2

isbn = '7513300712'

url = '

category_pattern = re.compile(r'Category: *.*, ')

html = urllib2.urlopen(url).read()

category_info = category_pattern.findall(html)

if len(category_info) > 0 :

print category_info[0]

else:

print 'get category failed.'

输出:

Category: 现当代小说, 小说,

2.选择合适的定位元素:

由于页面中只有一行“Category:” 信息,正则表达式提取就行,如果有很多行的话就需要缩小查找范围了,BeautifulSoup库就可以用来定位查找范围。通过分析可知,包含所需“Category:” 最近一层的div 是

,仔细观察,外层还有一个
,而
也是一样,这样如果使用它们来定位范围的话,使用find方法返回的tag对象是最先找到的外层div,范围不够小;使用findAll,返回的tag对象列表还需要遍历,综合得出用
作为定位元素,find方法定位返回的范围够小,又不需要对find结果进行遍历。

使用urllib2 + Beautiful Soup 3 + re 再来提取一次 (Beautiful Soup最新版本为4.4,兼容python3和python2,BS4跟BS3在导包方式上有点差别):import re,urllib2

from bs4 import BeautifulSoup

isbn = '7513300712'

url = 'http://openisbn.com/isbn/{0}/'.format(isbn)

category_pattern = re.compile(r'Category: *.*, ')

html = urllib2.urlopen(url).read()

soup = BeautifulSoup(html)

div_tag = soup.find('div',{'class':'Article'})

category_info = category_pattern.findall(str(div_tag))

if len(category_info) > 0 :

print category_info[0]

else:

print 'get category failed.'

输出:

Category: 现当代小说, 小说,

3. 抓取js渲染的内容:

用baidu搜索日历,获取结果页中的节假日日期

像上次一样直接使用urllib打开网页,发现返回的html中并没有期望得到的内容,原因是我通过浏览器所看到的页面内容实际是等js渲染完成后最终展现的,中间还包含了多次的ajax请求,这样使用urllib一次就不能胜任了,此时就可以让selenium上场了(webdriver用的phantomjs,需要提前下载phantomjs放到当前的PATH路径下),由于要查找的标识

包含了多个,所以这次使用的方法是findAll,然后再对返回的结果进行遍历,解析每个tag对象的a属性,如果包含了“休”字标识,那么这一天就是节假日。import re

import urllib

from selenium import webdriver

from BeautifulSoup import BeautifulSoup

holiday_list = []

url = 'http://www.baidu.com/s?' + urllib.urlencode({'wd': '日历'})

date_pattern = re.compile(r'date="[\d]+[-][\d]+[-][\d]+"')

driver = webdriver.PhantomJS()

driver.get(url)

html = driver.page_source

driver.quit()

soup = BeautifulSoup(html)

td_div_list = soup.findAll('div',{'class':'op-calendar-new-relative'})

for td_tag in td_div_list:

href_tag = str(td_tag.a)

if href_tag.find('休') != -1:

holiday_date_list = date_pattern.findall(href_tag)

if len(holiday_date_list) > 0:

holiday_list.append(holiday_date_list[0].split('"')[1])

print holiday_list

输出:

['2016-4-2', '2016-4-3', '2016-4-4', '2016-4-30', '2016-5-1’]

4. 设置代理,抓取google play排行榜

selenium不仅可以很好的模拟浏览器行为,还可以将网页内容截图保存from selenium import webdriver

url = 'https://play.google.com/store/apps/top?hl=zh_CN'

proxy_setting = ['--proxy=127.0.0.1:10800', '--proxy-type=socks5']

driver = webdriver.PhantomJS(service_args=proxy_setting)

driver.get(url)

driver.maximize_window()

# driver.implicitly_wait(10)

top_group_list = driver.find_elements_by_css_selector('.id-cluster-container.cluster-container.cards-transition-enabled')

driver.get_screenshot_as_file('top.jpg’)

for top_group in top_group_list:

group_name = top_group.find_element_by_xpath('div/div[@class="cluster-heading"]/h2/a').text

for item in top_group.find_elements_by_class_name('title'):

print u'bound: {0} app: {1}'.format(group_name,item.text)

driver.quit()

原文链接:https://www.zhihu.com/question/35461941/answer/99930298

你可能感兴趣的:(python爬虫,入门+进阶)