为何开始爬英文网站?而不从中文呢网站入手?
最早,我是从写中文网站的爬虫开始的,过程中遇到各种各样关于编码的奇怪问题后,为了不打击我的信心,我先从英文网站开始吧。英文网站那么多,先从哪个开始呢? 由于自己现在还是研究生,用的最多的网站是web of science,因此先从这个网站开始吧。
版本号:1.0
实现功能:
缘由:有时候,我在搜索一个主题的时候,在web of science键入关键词后,会有很多很多的文献,一页一页的翻很慢,如果能把所有文献的题目一次性导出那该有方便。
在写之前,首先导入一些常见的用于爬虫的库
import requests
from lxml import etree
其中requests库是用来获取网站信息,例如编码方式,头部信息等等,以及向网站传递信息等等。而lxml中的etree则是根据需要来提取request库中得到的网页源代码中
的信息。
例如在web of science中输入主题词water,如图1显示搜索结果有69w多条,
每一页显示10篇文章的信息,查看一下第1-2页的URL(理解为网址),分别如下
第一页: http://apps.webofknowledge.com/summary.do?product=UA&colName=&qid=34&SID=8EVHgmFwQyO7vUv8d9U&search_mode=GeneralSearch&formValue(summary_mode)=GeneralSearch&update_back2search_link_param=yes&page=1
第二页:http://apps.webofknowledge.com/summary.do?product=UA&parentProduct=UA&search_mode=GeneralSearch&parentQid=&qid=34&SID=8EVHgmFwQyO7vUv8d9U&colName=&&update_back2search_link_param=yes&page=2
比较两个URL,可以发现二者只是page=后面的数字不一样,因此,可以根据总页数,构建URL。
以第一页为例,代码可以轻松的写出来了
import requests
from lxml import etree
url = " http://apps.webofknowledge.com/summary.do?product=UA&colName=&qid=34&SID=8EVHgmFwQyO7vUv8d9U&search_mode=GeneralSearch&formValue(summary_mode)=GeneralSearch&update_back2search_link_param=yes&page=1"
然后利用浏览器模拟人浏览网站,这里要用到response.get()方法,get()方法用法如下:
response.get(url,headers)
其中,url为要网站名,headers可以理解为爬虫的外衣,它是借助这个模拟浏览器,header信息可以按F12 找到,如图2:
其中最下面的Use-Agent即为headers的值,属性为字典形式,因此要写成
headers = {"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
}
然后使用get()方法浏览网站
r = requests.get(url,headers=headers)
r.encoding = r.apparent_encoding
r.encoding = r.apparent_encoding
这句一般可以当做模板,是关于网站编码方式的。对于英文网站,不写也没关系。但是,对于中文一定要注意编码方式,否则会很心累的(难受)。
网页源代码是存放在r的text属性中的(说一下,text存放文本信息,而content存放的是二进制信息)。
了解过一点HTML语言的人都知道,网页源代码是由一个个标签组成的,比如<div>...</div>,标签是对称的。但有的网站可能标签并不是对称的,由头但没有尾,因此要让网页源代码更规范一点,这样更加有利于从中找到我们需要的信息。这里就要用到etree中的HTML方法了。它的作用就是让源代码更加规范。
html = etree.HTML(r.text)
好了。我们下面就要从源代码里找到文章的题目了
按下F12键,定位到文章题目那边,在图3中可以发现
文章的题目藏在a标签(属性为"smallV110 snowplow-full-record")下的value的文本中,所以很快就写出标题(title)的xpath路径
xpath('//a[@class="smallV110 snowplow-full-record"]/value/text()')
等等,不要高兴的太早,得到的结果中并没有包含自标签下的文字,所以text()方法只能获得当前标签下的文本,如果还想要获得子节点下的文本,需要用到string()方法
因此代码及解释如下:
names= html.xpath('//a[@class="smallV110 snowplow-full-record"]/value')
这步是为了得到所有value下的内容,names为列表,为可迭代对象,为了得到其中每一个元素,需要用for in
titles = []
for name in names:
titles.append(name.xpath('sting(.)')
其中点(·)表示当前节点下(一种省略的写法)
其实最简单的写法是用列表表达式写:
titles = [name.xpath('sting(.)') for name in names]
最后的代码如下
import requests
from lxml import etree
# import html
#下载一个网页
#登录 (可以写成函数)
headers = {"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
}
url = "http://apps.webofknowledge.com/summary.do?product=UA&parentProduct=UA&search_mode=GeneralSearch&parentQid=&qid=34&SID=8EVHgmFwQyO7vUv8d9U&&update_back2search_link_param=yes&page=1"
r = requests.get(url,headers=headers)
r.encoding = r.apparent_encoding
html = etree.HTML(r.text)
names= html.xpath('//a[@class="smallV110 snowplow-full-record"]/value') #names为list属性 names列表有10个元素,对应每个标题
#读取出每个文献的题目
# print(len(names))
titles = [name.xpath('string(.)') for name in names]
for i in titles:
print(i)
结果如下
Ozone ultrafine bubble water induces the cellular signaling involved in oxidative stress responses in human periodontal ligament fibroblasts
Development of Oil-in-Water Microemulsions and Evaluation of Its Presence in the Treatment of Produced Water.
Detection of multi-antibiotic resistant Campylobacter coli and Campylobacter jejuni in beef, mutton, chicken and water buffalo meat in Ahvaz, Iran
An investigation of the concurrency of anti-Neospora antibody and parasitemia in water buffalo (Bubalus bubalis) in northwest of Iran
Adaptation of multiple regression analysis to identify effective factors of water losses in water distribution systems
Water Pipe Smoking Reduction in the Male Adolescent Students: An Educational Intervention Using Multi-Theory Model
The Assessment of Trihalomethanes Concentrations in Drinking Water of Hamadan and Tuyserkan Cities, Western Iran and Its Health Risk on the Exposed Population
Validity of a single antibody-based lateral flow immunoassay depending on graphene oxide for highly sensitive determination of E. coli O157:H7 in minced beef and river water.
Effect of dietary fiber-rich fractions on texture, thermal, water distribution, and gluten properties of frozen dough during storage.
Ferrocene-based nanoporous organic polymer as solid-phase extraction sorbent for the extraction of chlorophenols from tap water, tea drink and peach juice samples.