主要以豆瓣图书首页的新书速递为例,练习爬虫过程中的请求网页的方式,还有分别用三种方式来解析爬到的网页文档
1.请求网页
可以用urllib2,open(),也可以用request(),这里对这两个库的区别不做细讲,主要讲讲爬虫过程中的普通请求方式和伪装浏览器请求。
普通请求:
# 普通方式读取 douban_book_html = urllib2.urlopen("https://book.douban.com/").read() print douban_book_html
但是有些网站会有些抵御爬虫的策略,比如说根据有没有请求头来判断是不是爬虫 我们可以通过开发者工具查看请求头:
伪装方法:
headers = [""]
request.add_header("User-Agent", random.choice(headers))
另外还有网站会根据IP来判断是不是爬虫,这时候就需要代理IP
代理IP的方法:
proxies = ['']
proxy_support = urllib2.ProxyHandler({'http': random.choice(proxies)})
opener = urllib2.build_opener(proxy_support)
urllib2.install_opener(opener)
2.三种方法解析网页
2.1正则匹配:
正则表达式我还不是很熟悉,这里推荐一篇学习正则表达式的好文章: 30分钟了解正则表达式
import re
book_info = re.findall("<a href=\"(.+?)\" title=(.+?)>", douban_book_html)
print book_info
2.2 BeautifulSoup
from bs4 import BeautifulSoup
soup = BeautifulSoup(douban_book_html, "lxml")
# print soup.prettify()
book_cover = soup.find_all("div", class_='cover')
book_info = []
for book in book_cover:
for link in book.find_all('a'):
book_link = link.get('href').encode('utf-8')
book_name = link.get('title')
if book_name is None: # 数据类型判断:三种方法 1. if a is str: 2.type(a) 3.isinstance(a,str)
book_name = '无'
else:
book_name = book_name.encode('utf-8')
one_book_info = (book_link, book_name)
book_info.append(one_book_info)
在解析豆瓣的新书速递时,有些书名居然是None类型,而我想存在txt文件中,None类型的不能索引以及存入txt文件,报什么错误我忘记了,所以用了一个判断语句来识别是否为空。在爬很多页面时,最麻烦的就是这些没有数据的节点的处理了,不单止影响你存文件,爬不到数据还会直接中断程序。我在另外一篇博客爬蚂蜂窝的旅游景点时也是遇到没有数据的,处理起来很费时间,如果有大神看到,希望给点意见,关于系统处理没有数据的情况的,谢谢!
3.lxml
import lxml.html
html = lxml.html.fromstring(douban_book_html)
print html
books = html.cssselect('div.cover a')
# books = html.xpath('//div[@class="cover"]')
book_info = []
for book in books:
# etree 中可以用get()来获取属性的值
book_link = book.get('href').encode('utf-8')
book_name = book.get('title')
if book_name is None: # 数据类型判断:三种方法 1. if a is str: 2.type(a) 3.isinstance(a,str)
book_name = '无'
else:
book_name = book_name.encode('utf-8')
one_book_info = (book_link, book_name)
book_info.append(one_book_info)
cssselect()和xpath()实在是太好用了!
3.结果
源代码我就不贴了,以后会放到github上