一、使用XPath抓取静态网页内容的基本流程
首先是引入库:
import requests
from lxml import etree
然后提取HTML内容
url='https://book.douban.com/top250'
data=requests.get(url).text
s=etree.HTML(data)
最后提取想要的内容
用浏览器(我用的火狐)打开目标网页(比如豆瓣Top500),按F12,选中要抓取的元素,右键复制XPath,如图:
BookNameCh=s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/text()')
看看效果
print(BookNameCh)
如图:
VS Code中的调试结果
二、使用replace进行字符串的初步处理
可以看到输出结果中有很多空格和转行,很不美观,我们可以使用replace对它进行初步处理
引入库:
import re
构建处理函数:
比如q=q.replace(' ','')
就是将空格替换为空值,实现了去空格
def mystring(p):
q=str(p)
q=q.replace(' ','')
q=q.replace('\\n','')
q=q.replace('[','')
q=q.replace(']','')
q=q.replace('\'','')
q=q.replace('\"','')
q=q.replace(',','')
return q
再来看一下效果:
BookNameCh=mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/text()'))
print(BookNameCh)
如图:
处理后输出的结果
三、多页多个内容的抓取
1.单页中多个内容的抓取
比较第一本书和第二本书的xpath,发现只是table[]不同而已,通过循环结构即可实现
for j in range(1,26):
BookNameCh.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/div[1]/a/text()'.format(j))))
2.翻页
比较第一页和第二页的网址的区别,发现只是?start=跟的数不同,且以25为步长递增,通过循环结构也容易实现
for i in range(10):
url='https://book.douban.com/top250?start={}'.format(i*25)
#url='https://book.douban.com/top250'
3.使用数组组织抓到的数据
定义一个数组
BookNameCh=[]
将数据填入数组中
BookNameCh.append(数据)
输出数据
print(BookNameCh[i*25+j-1])
四、将数据写入本地文件
为了让其他软件能够处理,我们需要将数据写入本地文件
with open('booktop250.csv','w',encoding='utf-8') as f:
f.write("BookNameCh,BookNameFo,BookInfo,BookScore,ReviewerNumber,Comment\n")
for i in range(10):
for j in range(1,26):
f.write("{},{},{},{},{},{}\n".format(BookNameCh[i*25+j-1],BookNameEn[i*25+j-1],BookInfo[i*25+j-1],BookScore[i*25+j-1],ReviewerNumber[i*25+j-1],Comment[i*25+j-1]))
用SPSS查看一下所获得的数据,如图:
在SPSS中查看所获得的数据
下面是完整代码:
import requests
from lxml import etree
import re
def mystring(p):
q=str(p)
q=q.replace(' ','')
q=q.replace('\\n','')
q=q.replace('[','')
q=q.replace(']','')
q=q.replace('\'','')
q=q.replace('\"','')
q=q.replace(',','')
return q
BookNameCh=[]
BookNameEn=[]
BookInfo=[]
BookScore=[]
ReviewerNumber=[]
Comment=[]
for i in range(10):
url='https://book.douban.com/top250?start={}'.format(i*25)
#url='https://book.douban.com/top250'
data=requests.get(url).text
s=etree.HTML(data)
for j in range(1,26):
BookNameCh.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/div[1]/a/text()'.format(j))))
BookNameEn.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/div[1]/span/text()'.format(j))))
BookInfo.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/p[1]/text()'.format(j))))
BookScore.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/div[2]/span[2]/text()'.format(j))))
pReviewerNumber=mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/div[2]/span[3]/text()'.format(j)))
pReviewerNumber=pReviewerNumber.replace('人评价)','')
pReviewerNumber=pReviewerNumber.replace('(','')
pReviewerNumber=int(pReviewerNumber)
ReviewerNumber.append(pReviewerNumber)
Comment.append(mystring(s.xpath('/html/body/div[3]/div[1]/div/div[1]/div/table[{}]/tr/td[2]/p[2]/span/text()'.format(j))))
print(BookNameCh[i*25+j-1])
print(BookNameEn[i*25+j-1])
with open('booktop250.csv','w',encoding='utf-8') as f:
f.write("BookNameCh,BookNameFo,BookInfo,BookScore,ReviewerNumber,Comment\n")
for i in range(10):
for j in range(1,26):
f.write("{},{},{},{},{},{}\n".format(BookNameCh[i*25+j-1],BookNameEn[i*25+j-1],BookInfo[i*25+j-1],BookScore[i*25+j-1],ReviewerNumber[i*25+j-1],Comment[i*25+j-1]))
网友评论