Python 网页爬虫
一、要解决的问题
需要解决的是根据自定义的关键词自动搜索google学术,解析搜索到的网页,下载所有相应的论文的PDF链接。这里我们采用Python来实现,
二、Python入门
python 自动缩进:shift+table整块向左缩进,table向右缩进,在修改整块代码时很有用比如将函数变成单独执行时。
了解python的变量,包,函数定义等
三、网页知识
3.1 浏览网页的过程
打开网页的过程其实就是浏览器作为一个浏览的“客户端”,向服务器端发送了 一次请求,把服务器端的文件“抓”到本地,再进行解释、展现。
HTML是一种标记语言,用标签标记内容并加以解析和区分。
浏览器的功能是将获取到的HTML代码进行解析,然后将原始的代码转变成我们直接看到的网站页面。
3.2 URI和URL的概念
简单的来讲,URL就是在浏览器端输入的 http://www.baidu.com 这个字符串。
在理解URL之前,首先要理解URI的概念。
URL是URI的一个子集。它是Uniform Resource Locator的缩写,译为“统一资源定位 符”。
通俗地说,URL是Internet上描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
URL的一般格式为(带方括号[]的为可选项):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
URL的格式由三部分组成:
①第一部分是协议(或称为服务方式)。
②第二部分是存有该资源的主机IP地址(有时也包括端口号)。
③第三部分是主机资源的具体地址,如目录和文件名等。
第一部分和第二部分用“://”符号隔开,
第二部分和第三部分用“/”符号隔开。
第一部分和第二部分是不可缺少的,第三部分有时可以省略。
参考至:http://blog.csdn.net/pleasecallmewhy/article/details/8922826
四、网页爬虫
4.1 解决google无法登陆
因为要抓取的google学术的页面,但是google在中国屏蔽了,所以需要在电脑上先配置好goagent,然后进行代理配置,代码如下
proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
4.2 解决抓取屏蔽
对于少量的查询,但如果要进行上千上万次的查询,上面的方法就不再有效了, Google会检测你请求的来源,如果我们利用机器频繁爬取Google的搜索结果,不多久就Google会block你的IP,并给你返回503 Error页面。可以设置URL请求的headers, 伪装我们的user agent。简单的说,user agent就是客户端浏览器等应用程序使用的一种特殊的网络协议, 在每次浏览器(邮件客户端/搜索引擎蜘蛛)进行 HTTP 请求时发送到服务器,服务器就知道了用户是使用什么浏览器(邮件客户端/搜索引擎蜘蛛)来访问的。 有时候为了达到一些目的,我们不得不去善意的欺骗服务器告诉它我不是在用机器访问你。
user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \
(KHTML, like Gecko) Element Browser 5.0', \
'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \
'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \
'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \
Version/6.0 Mobile/10A5355d Safari/8536.25', \
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \
Chrome/28.0.1468.0 Safari/537.36', \
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
4.3 正则表达式解析网页
使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。比如:现在的需求是要找到一个正则表达式来匹配后缀是“.pdf”的字符串。
inputURL = 'http://scholar.google.com/scholar?q=text+detection&btnG=&hl=en&as_sdt=0%2C5'
request = urllib2.Request(inputURL)
index = random.randint(0, 9)
user_agent = user_agents[index]
request.add_header('User-agent', user_agent)
f = urllib2.urlopen(request).read() #打开网页
print f
localDir = 'E:\download\\' #下载PDF文件需要存储在本地的文件夹
urlList = [] #用来存储提取的PDF下载的url的列表
for eachLine in f: #遍历网页的每一行
line = eachLine.strip() #去除行首位的空格,习惯性写法
if re.match('.*PDF.*', line): #去匹配含有“PDF”字符串的行,只有这些行才有PDF下载地址
wordList = line.split('\"') #以"为分界,将该行分开,这样就将url地址单独分开了
for word in wordList: #遍历每个字符串
if re.match('.*\.pdf$', word): #去匹配含有“.pdf”的字符串,只有url中才有
urlList.append(word) #将提取的url存入列表
for everyURL in urlList: #遍历列表的每一项,即每一个PDF的url
wordItems = everyURL.split('/') #将url以/为界进行划分,为了提取该PDF文件名
for item in wordItems: #遍历每个字符串
if re.match('.*\.pdf$', item): #查找PDF的文件名
PDFName = item #查找到PDF文件名
localPDF = localDir + PDFName #将本地存储目录和需要提取的PDF文件名进行连接
try:
urllib.urlretrieve(everyURL, localPDF) #按照url进行下载,并以其文件名存储到本地目录
except Exception, e:
continue
五、遇到的问题及解决
5.1 采用http协议
打开google的时候,如果用https协议无法打开网页取到内容,只有采用http协议才可以,原因可能是https采用加密协议。
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 13 16:27:02 2015
@author: dwanminghuang
"""
import urllib #导入urllib模块
import urllib2 #导入urllib2模块
import re
import re, random, types #导入正则表达式模块:re模块
user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \
(KHTML, like Gecko) Element Browser 5.0', \
'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \
'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \
'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \
Version/6.0 Mobile/10A5355d Safari/8536.25', \
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \
Chrome/28.0.1468.0 Safari/537.36', \
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
proxy = urllib2.ProxyHandler({"http":"http://127.0.0.1:8087","https":"https://127.0.0.1:8087"})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
inputURL = 'http://scholar.google.com/scholar?q=text+detection&btnG=&hl=en&as_sdt=0%2C5'
request = urllib2.Request(inputURL)
index = random.randint(0, 9)
user_agent = user_agents[index]
request.add_header('User-agent', user_agent)
f = urllib2.urlopen(request).read() #打开网页
print f
localDir = 'E:\download\\' #下载PDF文件需要存储在本地的文件夹
urlList = [] #用来存储提取的PDF下载的url的列表
for eachLine in f: #遍历网页的每一行
line = eachLine.strip() #去除行首位的空格,习惯性写法
if re.match('.*PDF.*', line): #去匹配含有“PDF”字符串的行,只有这些行才有PDF下载地址
wordList = line.split('\"') #以"为分界,将该行分开,这样就将url地址单独分开了
for word in wordList: #遍历每个字符串
if re.match('.*\.pdf$', word): #去匹配含有“.pdf”的字符串,只有url中才有
urlList.append(word) #将提取的url存入列表
for everyURL in urlList: #遍历列表的每一项,即每一个PDF的url
wordItems = everyURL.split('/') #将url以/为界进行划分,为了提取该PDF文件名
for item in wordItems: #遍历每个字符串
if re.match('.*\.pdf$', item): #查找PDF的文件名
PDFName = item #查找到PDF文件名
localPDF = localDir + PDFName #将本地存储目录和需要提取的PDF文件名进行连接
try:
urllib.urlretrieve(everyURL, localPDF) #按照url进行下载,并以其文件名存储到本地目录
except Exception, e:
continue