-
Notifications
You must be signed in to change notification settings - Fork 0
/
爬虫1:Requests+Xpath 爬取豆瓣电影TOP .py
181 lines (102 loc) · 4.54 KB
/
爬虫1:Requests+Xpath 爬取豆瓣电影TOP .py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# coding: utf-8
# In[7]:
# 1 Requests+Xpath 菜鸟爬取豆瓣TOP
# 电影名称
'''
Requests+Xpath 爬取豆瓣电影
安装 Python 应用包
pip install requests
pip install lxml
获取元素的Xpath信息并获得文本:
手动获取:定位目标元素,在网站上依次点击:右键 > 检查
file=s.xpath('元素的Xpath信息/text()')
快捷键“shift+ctrl+c”,移动鼠标到对应的元素时即可看到对应网页代码:
在电影标题对应的代码上依次点击 右键 > Copy > Copy XPath,获取电影名称的Xpath:
'''
import requests
from lxml import etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
film=s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/@title')
print(film)
# In[1]:
# 2 全部书名
'''
浏览器经常会自己在里面增加多余的 tbody 标签,我们需要手动把这些标签删掉。
分别复制《追风筝的人》、《小王子》、《围城》、《解忧杂货店》的 xpath 信息进行对比:
//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[2]/tbody/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[3]/tbody/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[4]/tbody/tr/td[2]/div[1]/a
比较可以发现书名的 xpath 信息仅仅 table 后的序号不一样,并且跟书的序号一致,于是去掉序号(去掉 tbody),我们可以得到通用的 xpath 信息:
//*[@id=“content”]/div/div[1]/div/table/tr/td[2]/div[1]/a
'''
import requests
from lxml import etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
file=s.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a/@title')
for title in file:
print(title)
# In[4]:
# 3 爬取页面多个信息时的数据准确匹配问题
# strip(“(”) 表示删除括号, strip() 表示删除空白符。
'''
问题:我们默认书名和评分是正确的信息,如果某一项少爬或多爬了信息,匹配错误
思路:书名的标签肯定在这本书的框架内,以每本书为单位,分别取获取对应的信息,完全匹配
//*[@id=“content”]/div/div[1]/div/table[1] #整本书
//*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a #书名
//*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2] #评分
我们发现,书名和评分 xpath 的前半部分和整本书的 xpath 一致的, 那我们可以通过这样写 xpath 的方式来定位信息:
file=s.xpath(“//*[@id=“content”]/div/div[1]/div/table[1]”)
title =div.xpath(“./tr/td[2]/div[1]/a/@title”)
score=div.xpath(“./tr/td[2]/div[2]/span[2]/text()”)
'''
import requests
import time
from lxml import etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
file=s.xpath('//*[@id="content"]/div/div[1]/div/table')
for div in file:
title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]
href = div.xpath("./tr/td[2]/div[1]/a/@href")[0]
score = div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]
num = div.xpath("./tr/td[2]/div[2]/span[3]/text()")[0].strip("(").strip().strip(")")
scribe = div.xpath("./tr/td[2]/p[2]/span/text()")
time.sleep(2)
print("{}{}{}{}{}".format(title,href,score,num,scribe[0]))
# In[6]:
# 翻页
'''
https://book.douban.com/top250?start=0 #第一页
https://book.douban.com/top250?start=25 #第二页
https://book.douban.com/top250?start=50 #第三页
以每页25为单位,递增25,只是 start=()的数字不一样
写一个循环
for a in range(3):
url = 'https://book.douban.com/top250?start={}'.format(a*25)
#3个页面,用 a*25 保证以25为单位递增
'''
import requests
import time
from lxml import etree
for a in range(3):
url = 'https://book.douban.com/top250?start={}'.format(a*25)
data = requests.get(url).text
s=etree.HTML(data)
file=s.xpath('//*[@id="content"]/div/div[1]/div/table')
time.sleep(3)
for div in file:
title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]
href = div.xpath("./tr/td[2]/div[1]/a/@href")[0]
score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]
num=div.xpath("./tr/td[2]/div[2]/span[3]/text()")[0].strip("(").strip().strip(")").strip()
scrible=div.xpath("./tr/td[2]/p[2]/span/text()")
if len(scrible) > 0:
print("{},{},{},{},{}\n".format(title,href,score,num,scrible[0]))
else:
print("{},{},{},{}\n".format(title,href,score,num))