实现python爬虫的简单细节分析

爬虫部分

1. 这肯定得加个User-Agent,不然连不上

这里面可能还要加上cookie,这个有点诡异。你说,有一个值等于 0, 60 ,怎么办?把它变成[],还是””???

2. 常规路数,使用bs4

1
2
3
4
5
6
7
8
9
10
11
12
def getHtml(url):
try:
r = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
r.raise_for_status()
r.encoding = "utf-8"
return r.text
except:
print("Failed!!!")

url = BASE_URL + str(year) + '.html'
html = getHtml(url)
soup = BeautifulSoup(html, "html.parser")

然后用find和find_all找到所有相关标签,当然可以指定class=???

3. 爬取表格

1
2
3
4
5
6
7
8
comment_list = soup.find('table', attrs={'class': 'table'}).find_all('tr')

for j in comment_list[1:]: # tr2[1:]遍历第1列到最后一列,表头为第0列
td = j.find_all('td') # td表格
Rate = td[0].get_text().strip() # 遍历排名
Country = td[1].get_text().strip() # 遍历国家
Area = td[2].get_text().strip() # 遍历洲
Num = td[3].get_text().strip() # 遍历人数

自己看,因为有的会带有列名,注意。

4. 正则表达

提取括号内的内容:

1
re.findall(r".*\((.*)\)", Num)

由于提取之后会变成123,123这样的玩意,所以,将其replace替换

1
tNum = "".join(re.findall(r".*\((.*)\)", Num)).replace(',', '')

好了,这里又将遇到问题:因为有的数据因数字较小,所以不会有(),那么re.findall之后的内容就只有None,如果再进行float,将会报错:ValueError。这时我们可以运用异常处理来解决:

1
2
3
4
try:
fNum = float(tNum)
except ValueError:
fNum = float(Num)

5. 字典与列表的基本应用

这里我只用了很少,不管了,先写下来:

  1. 添加字典:直接dict[yourkey]=??就可以
  2. 添加列表数据:listData.append(youwant)
  3. 删除字典:dict.pop(key)

数据读写部分

这里都是对excel表格的操作。

1. 读excel

打开文件并且选择相应的sheet

注意,因为我存的是xls,所以不能用openxls来进行读,而应该用xlrd

1
2
workbook= xlrd.open_workbook(filepath)
worksheet=workbook.sheet_by_name('ALLdata')

获取最大行列数

1
2
mrow=worksheet.nrows
mcol=worksheet.ncols

读单元格

1
worksheet.cell(row, colum).value

2. 写excel

新建

1
2
3
workbook = xlwt.Workbook()
#添加sheet表
sheet = workbook.add_sheet('ALLdata', cell_overwrite_ok=True)

写入

1
sheet.write(row, col, str(value))

这里value必须是str类型,不然会报错!

保存

1
workbook.save(filename)

数据分析部分

1. 数据拟合及预测

拟合函数生成

1
2
3
f1= np.polyfit(xdata, ydata, 3)
p1 = np.poly1d(f1)
yvals1 = p1(xdata)

注:xdata,ydata是x,y坐标点的系列值,3是曲线拟合次数,此时p1即3次多项式。先把xdata代入p1多项式中,将会生成yvals1相应的值,这个可以作为预测值。

2. 图像生成

1
2
3
4
5
6
7
8
9
ln1 = plt.plot(xdata, ydata, color='red', label='original values')
pln1 = plt.plot(xdata, yvals1, color='blue', linewidth=2.0, linestyle='-.', label='polyfit values')
# yvals1 = p1(xdata) # 拟合y值
plt.xlabel('year')
plt.ylabel('population')
plt.legend(loc=4)
# plt.show()
plt.savefig(country+".png")
plt.close()

注:

  1. ln1是原来的图,那个label是标签(指定这个曲线是啥玩意)
  2. pln1是拟合之后的值,使用拟合之后的yvals1。
  3. linestyle=’-.’是线的类型,有– -. - 空等等
  4. 而plt.xlabel是指定x轴是啥
  5. plt.show()展示图像
  6. plt.savefig(filename)保存图像为filename
  7. 如果不关闭,那么这些xlabel和ylabel会混杂在一起,所以必须使用plt.close()