为什么 e.xpath('//tr[@class="item"]/td[2]/div[1]/a|span/text() ')获取到的是元素而不是元素的文本
时间: 2024-01-23 08:03:15 浏览: 138
这是因为XPath表达式 `//tr[@class="item"]/td[2]/div[1]/a|span/text()` 中的 `a` 和 `span` 都是元素节点,而不是文本节点。如果要获取元素节点的文本内容,应该在节点名称后面加上 `/text()`。因此,正确的XPath表达式应该是 `//tr[@class="item"]/td[2]/div[1]/a/text()|//tr[@class="item"]/td[2]/div[1]/span/text()`。这样才能获取到 `a` 和 `span` 元素节点下的文本内容。
相关问题
def parse(self, response): res = Selector(response) items = RenrenchesipderItem() items['id'] = res.xpath('//div[@class="detail-wrapper"]/@data-encrypt-id').extract()[0] # 标题 items['title'] = res.xpath('//div[@class="title"]/h1/text()').extract()[0] # 客户出价 items['price'] = res.xpath('//div[@class="middle-content"]/div/p[2]/text()').extract()[0] # 市场价 items['new_car_price'] = res.xpath('//div[@class="middle-content"]/div/div[1]/span/text()').extract()[0] # 首付款 down_payment = res.xpath('//div[@class="list"]/p[@class="money detail-title-right-tagP"]/text()') # 月供 monthly_payment = res.xpath('//[@id="basic"]/div[2]/div[2]/div[1]/div[3]/div[2]/p[5]/text()') # 判断是否可以分期购买 if down_payment and monthly_payment: items['staging_info'] = [down_payment.extract()[0], monthly_payment.extract()[0]] # 服务费 items['service_fee'] = res.xpath('///div[1]/p[2]/strong/text()').extract()[0] # 服务项 items['service'] = res.xpath('//[@id="js-box-service"]/table/tr/td/table/tr/td/text()').extract() # 车辆上牌时间 里程 外迁信息 items['info'] = res.xpath('///div[2]/div[2]/div[1]/div[4]/ul/li/div/p/strong/text()').extract() # 车辆排量 items['displacement'] = \ res.xpath('//[@id="basic"]/div[2]/div[2]/div[1]/div[4]/ul/li[4]/div/strong/text()').extract()[0] # 车辆上牌城市 items['registration_city'] = res.xpath('///@licensed-city').extract()[0] # 车源号 items['options'] = \ res.xpath('//*[@id="basic"]/div[2]/div[2]/div[1]/div[5]/p/text()').extract()[0].strip().split(":")[1] # 判断是都有图片 if res.xpath('//div[@class="info-recommend"]/div/img/@src'): # 车辆图片 items['car_img'] = res.xpath('//div[@class="info-recommend"]/div/img/@src').extract()[0] # 车辆所在城市 items['city'] = res.xpath('//div[@rrc-event-scope="city"]/a[@class="choose-city"]/text()').extract()[0].strip() # 车辆颜色 items['color'] = res.xpath('//div[@class="card-table"]/table/tr/td[2]/text()').extract()[0] 解释一下每一句话
这是一个 Python 的 scrapy 爬虫程序中的一个解析函数,主要作用是从网页中提取出需要的数据并存储到 items 中。具体解释如下:
```python
def parse(self, response):
res = Selector(response) # 使用 scrapy 的 Selector 对象解析 response
items = RenrenchesipderItem() # 定义一个 items 对象用于存储数据
# 从网页中提取出 id、标题、客户出价、市场价、首付款、月供、服务费、服务项、车辆上牌时间、里程、外迁信息、车辆排量、车辆上牌城市、车源号、车辆颜色等数据
items['id'] = res.xpath('//div[@class="detail-wrapper"]/@data-encrypt-id').extract()[0]
items['title'] = res.xpath('//div[@class="title"]/h1/text()').extract()[0]
items['price'] = res.xpath('//div[@class="middle-content"]/div/p[2]/text()').extract()[0]
items['new_car_price'] = res.xpath('//div[@class="middle-content"]/div/div[1]/span/text()').extract()[0]
down_payment = res.xpath('//div[@class="list"]/p[@class="money detail-title-right-tagP"]/text()')
monthly_payment = res.xpath('//[@id="basic"]/div[2]/div[2]/div[1]/div[3]/div[2]/p[5]/text()')
if down_payment and monthly_payment:
items['staging_info'] = [down_payment.extract()[0], monthly_payment.extract()[0]]
items['service_fee'] = res.xpath('///div[1]/p[2]/strong/text()').extract()[0]
items['service'] = res.xpath('//[@id="js-box-service"]/table/tr/td/table/tr/td/text()').extract()
items['info'] = res.xpath('///div[2]/div[2]/div[1]/div[4]/ul/li/div/p/strong/text()').extract()
items['displacement'] = res.xpath('//[@id="basic"]/div[2]/div[2]/div[1]/div[4]/ul/li[4]/div/strong/text()').extract()[0]
items['registration_city'] = res.xpath('///@licensed-city').extract()[0]
items['options'] = res.xpath('//*[@id="basic"]/div[2]/div[2]/div[1]/div[5]/p/text()').extract()[0].strip().split(":")[1]
if res.xpath('//div[@class="info-recommend"]/div/img/@src'):
items['car_img'] = res.xpath('//div[@class="info-recommend"]/div/img/@src').extract()[0]
items['city'] = res.xpath('//div[@rrc-event-scope="city"]/a[@class="choose-city"]/text()').extract()[0].strip()
items['color'] = res.xpath('//div[@class="card-table"]/table/tr/td[2]/text()').extract()[0]
return items # 返回 items 对象
```
其中,Selector 对象是 scrapy 中提供的一种选择器,可以方便地从 HTML 或 XML 中提取数据。extract() 方法用于获取提取的数据,[0] 则是因为返回的是一个列表,需要取出其中的第一个元素。此外,还有一些判断语句用于处理数据缺失或判断是否存在该数据,如 if down_payment and monthly_payment: 判断是否可以分期购买。最后,将所有数据存储在 items 对象中并返回。
优化这段代码 for p in range(1,1190): try: # print(browser.page_source) # 输出网页源码 time.sleep(1) html = etree.HTML(browser.page_source) content_html = html.xpath('//div[@class="table-responsive"]/table/tbody[@class="data-table"]/tr') for html_ in content_html: No_id = html_.xpath('.//td[2]/text()') url2_list = html_.xpath('.//td[3]/div/text()') url2_list = url2_list[0].replace('www.', '').rstrip('/') # url2_list=url2_list[0].replace('https://www.','').replace('http://www.','').replace('https://','').replace('http://','').rstrip('/') # language_list=html_.xpath('.//div[@class="table__summary table__summary--inventory-verified"]/div[12]/div/text()') category_list = html_.xpath('.//td[4]/div/div/div[1]/span/text()') category_list = '、'.join(category_list) # category_list='、'.join(category_list) # 提供者数量 performer_list = html_.xpath('.//td[10]/text()') performer_list = '$' + performer_list[0] last = [p,No_id[0], '', 'globexportal.net', url2_list, '', '', category_list, '', '平台', performer_list] print(last) with open('globexportal.net.1.csv', 'a+', newline='', encoding='utf_8_sig') as fp: writer = csv.writer(fp) writer.writerow(last) pyautogui.scroll(-40, x=960, y=720) except Exception as e: print(str(e))
根据您提供的代码片段,可以对其进行一些优化。首先,可以将文件写入操作放在循环之外,减少频繁的文件写入操作。另外,可以使用更简洁的方法来处理XPath选择器的结果。以下是优化后的代码:
```python
import csv
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from lxml import etree
# 创建一个Chrome浏览器实例
s = Service('path/to/chromedriver') # 将路径替换为你的chromedriver路径
chrome_options = Options()
chrome_options.add_argument('--headless') # 设置为无界面模式
browser = webdriver.Chrome(service=s, options=chrome_options)
# 打开登录页面,登录
for p in range(1, 1190):
try:
time.sleep(1)
html = etree.HTML(browser.page_source)
content_html = html.xpath('//div[@class="table-responsive"]/table/tbody[@class="data-table"]/tr')
result = []
for html_ in content_html:
No_id = html_.xpath('.//td[2]/text()')[0]
url2_list = html_.xpath('.//td[3]/div/text()')[0].replace('www.', '').rstrip('/')
category_list = '、'.join(html_.xpath('.//td[4]/div/div/div[1]/span/text()'))
performer_list = '$' + html_.xpath('.//td[10]/text()')[0]
last = [p, No_id, '', 'globexportal.net', url2_list, '', '', category_list, '', '平台', performer_list]
result.append(last)
print(last)
with open('globexportal.net.1.csv', 'a+', newline='', encoding='utf_8_sig') as fp:
writer = csv.writer(fp)
writer.writerows(result)
# 模拟滚动
actions = ActionChains(browser)
actions.move_by_offset(960, 720).perform()
actions.send_keys(Keys.PAGE_DOWN).perform()
actions.reset_actions()
except Exception as e:
print(str(e))
# 关闭浏览器
browser.quit()
```
在优化后的代码中,使用XPath选择器时,直接使用索引来获取结果列表中的第一个元素,避免了使用变量并进行多余的操作。另外,将需要写入CSV文件的数据存储在一个列表中,然后一次性写入文件,减少了频繁的文件写入操作。
请确保已经正确导入所需的模块,并根据您的实际情况进行适当的调整和修改。另外,需要注意根据您的实际需求进行Chrome浏览器实例的配置,如使用无界面模式等。
阅读全文