1、首先需要导入本次爬取程序使用的库
import requests
import os
import csv
from fake_useragent import UserAgent
from lxml import etree
2、该项目使用了一个类,类中封装了四个方法,
(1)、使用init方法来初始化目标的url
(2)、使用get_data()方法来获取我本次需要采集的各种信息
(3)、使用shave_csv方法来对采集到的数据进行保存
(4)、使用call方法来调用获取数据方法的执行
(5)、使用main方法作为程序执行的入口
(1)、首先需要获取目标url
(2)、这里可以发现土地流转信息公有53页,所以在这里需要进行url的翻页。
(3)、在请求之前需要设置请求头来进行伪装,这里使用到了UserAgent的第三方库,它的内部包含了多个浏览器的请求头,UserAgent是识别浏览器的一串字符串,相当于浏览器的身份证,在利用爬虫爬取网站数据时,频繁更换UserAgent可以避免触发相应的反爬机制。fake-useragent对频繁更换UserAgent提供了很好的支持,可谓防反扒利器。我们每次发送requests请求时通过random从中随机获取一个随机UserAgent,两行代码即可完成UserAgent的不停更换。
在使用requests发送请求时需要设置headers,也就是浏览器伪装头部
(4)、使用lxml库进行解析获取下来的数据
lxml是python的一个解析库,支持HTML和XML格式的解析,XPath,全称XML Path Language,即XML路径语言,很明显是通过路径来定位,通俗点你可以想象成一个树状结构,会有很多节点分支,然后你再回过来看对应的HTML,如果还没看到过可以用谷歌浏览器打开任意网站,右键检查元素
所以在做爬虫时,我们完全可以使用 XPath 来做相应的信息抽取。
(5)、对url详情页翻页以后,明确需要爬取的字段
然后将范围缩小到这个div中
(6)、因为xpath获取到的信息为列表,所以这里使用enumerate函数将以某个字段作为参考长度来对其他字段进行获取信息。
(7)、获取结果
(8)、对获取到的数据使用csv模块进行保存为csv文件
(9)、在获取的过程中报了索引的错误,
(10)、经过一番查找原来是location字段在后面的信息中有的是为空的,所以在这里可以判断如果location字段的长度不等purpose字段的长度,则以空字符来补全。
(11)、成功获取数据:
# encoding:utf-8
import requests
import os
import csv
from fake_useragent import UserAgent
from lxml import etree
class YX(object):
def __init__(self):
self.url = 'https://www.tudinet.com/market-1126-0-0-0/list-pg{}.html'
def __call__(self, *args, **kwargs):
self.get_data()
def shave_csv(self, object, object1=["推出时间", "成交状态", "土地面积", "土地地址", "规划建筑面积", "规划用途", "土地位置"], name="宜兴市土流"):
# 判断是否已经有表头
if not os.path.exists("./{}.csv".format(name)):
with open("./{}.csv".format(name), 'a+', encoding='GB18030', newline="") as newcsvfile:
writer = csv.writer(newcsvfile)
writer.writerow(object1)
# 进行存储
with open("./{}.csv".format(name), 'a+', encoding='GB18030', newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(object)
def get_data(self):
headers = {
"User-Agent": UserAgent().random,
"Cookie": "PHPSESSID=03oa1b30chougrf33ve5bivua7; UM_distinctid=1727814d681617-0c17e0e54243d3-5d492f12-1fa400-1727814d682681; CNZZDATA1260759960=1749467275-1591148148-https%253A%252F%252Fwww.tuliu.com%252F%7C1591148148; Hm_lvt_70142fc2c205a27dbcb999d5a212ef38=1591152531; Hm_lpvt_70142fc2c205a27dbcb999d5a212ef38=1591152667"
}
for i in range(1, 54):
# 翻页
url = self.url.format(i)
# print(url)
response = etree.HTML(requests.get(url=url, headers=headers, verify=False).text)
# time.sleep(2)
# 缩小范围
scope = response.xpath("//article/section//div[2]")
for i in scope:
# 标题
title = i.xpath(".//dl/dt/a/@titl")[0]
# print(title)
# # print(title)
# 获取位置//dd/p[7]/text()
location = ["" if len(i) == 0 else i for i in i.xpath(".//dd/p[7]/text()")]
# # print(location)
# 获取推出时间
launch_time = ["" if len(i) == 0 else i for i in i.xpath(".//dd/p[1]/text()")]
# # print(launch_time)
# 获取成交状态
state = ["" if len(i) == 0 else i for i in i.xpath('.//dd/p[2]/text()')]
# # print(state)
# 获取土地面积
land_area = ["" if len(i) == 0 else i for i in i.xpath('.//dd/p[3]/text()')]
# # print(land_area)
# # 获取土地地址
land_address = ["" if len(i) == 0 else i for i in i.xpath('.//dd/p[4]/text()')]
# print(land_address)
# 获取规划面积
architecture_area = ["" if len(i) == 0 else i for i in i.xpath('.//dd/p[5]/text()')]
# print(architecture_area)
# 获取规划用途
purpose = ["" if len(i) == 0 else i for i in i.xpath('.//dd/p[6]/text()')]
# print(purpose)
if purpose.__len__() != location.__len__():
for i in range(purpose.__len__()-location.__len__()):
location.append("")
for i, index in enumerate(launch_time):
# 获取土地位置
launch_time2 = index
# print(location2)
# 获取推出时间
location2 = location[i]
# 获取成交状态
state2 = state[i]
# 获取土地面积
land_area2 = land_area[i]
# 获取土地地址
land_address2 = land_address[i]
# 获取规划面积
architecture_area2 = architecture_area[i]
# 获取规划用途
purpose2 = purpose[i]
print("打印",
[launch_time2, state2, land_area2, land_address2, architecture_area2, purpose2, location2])
self.shave_csv(
[launch_time2, state2, land_area2, land_address2, architecture_area2, purpose2, location2])
if __name__ == '__main__':
td = YX()
td()